录像功能简单实现&字幕srt保存

界面效果

这里写图片描述

功能介绍

照相机预览

  • 窗体的onCreate中添加
SurfaceHolder holder = surfaceView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.setKeepScreenOn(true);//保持屏幕高亮
  • surfaceCreated
@Override
public void surfaceCreated(SurfaceHolder holder) {
    surfaceHolder = holder;
    //初始化相机
    initCamera();
}
  • surfaceChanged
@Override
public void surfaceChanged(SurfaceHolder holder, int i, int i1, int i2) {
    surfaceHolder = holder;
    //开启相机预览
    cameraPreview();
}
  • surfaceDestroyed
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    surfaceView = null;
    surfaceHolder = null;
    //释放MediaRecorder及相机
    stopRecord();
    //释放MediaPlayer
    stopPlay();
}
  • initCamera:初始化相机
private void initCamera() {
    if (camera != null) {
        camera.release();
        camera = null;
    }
    try {
        //打开后置摄像头(此文未涉及前置摄像头)
        camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
        if (camera != null) {
            cameraPara = camera.getParameters();
            //可通过camera.getParameters().getSupportedVideoSizes()获取支持的大小
            cameraPara.setPreviewSize(600, 480);
            cameraPara.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
            camera.cancelAutoFocus();//连续自动对焦
            camera.setParameters(cameraPara);
        }
    } catch (Exception e) {
        e.printStackTrace();
        if (camera != null) {
            camera.release();
            camera = null;
        }
    }
}
  • cameraPreview:相机预览
private void cameraPreview() {
    if (camera != null) {
        try {
            camera.setPreviewDisplay(surfaceView.getHolder());
            camera.setDisplayOrientation(90);
            camera.startPreview();
            //设置闪光灯
            cameraPara.setFlashMode(isFlashOn ? Parameters.FLASH_MODE_TORCH : Parameters.FLASH_MODE_OFF);
            camera.setParameters(cameraPara);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

录像

  • startRecord:开始录制
private static final int RECORDER_MAX_LENGTH = 30 * 60 * 1000;//录像最大时长
private Handler handler = new Handler();
private long srtInterval = 1000;//字幕输出的时间间隔

private void startRecord() {
    //录像过程中显示时间
    hour = minute = second = 0;
    startRecordTime = new Date().getTime();
    handler.postDelayed(updateTimeRunnable, 1000);
    //录像过程中保存字幕文件
    lastSrtTime = "00:00:00,000";//上次输出srt的时间
    srtRowNum = 1;//字幕输出的行号
    handler.postDelayed(recordSrtRunnable, srtInterval);    

    //开始录制
    if (mediaRecorder == null) {
        mediaRecorder = new MediaRecorder();
    }
    if (camera == null) {
        initCamera();
        camera.setDisplayOrientation(90);
    }
    camera.unlock();
    mediaRecorder.setCamera(camera);
    try {
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        //设置输出的文件格式 
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);

        //与camera的previewSize需设置为一样
        mediaRecorder.setVideoSize(640, 480);
        mediaRecorder.setVideoFrameRate(30);
        mediaRecorder.setVideoEncodingBitRate(3 * 1024 * 1024);
        mediaRecorder.setOrientationHint(90);

        //设置记录会话的最大持续时间(毫秒)
        mediaRecorder.setMaxDuration(RECORDER_MAX_LENGTH);
        mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());

        mediaRecorder.setOutputFile(path);
        mediaRecorder.prepare();
        mediaRecorder.start();
    } catch (Exception e) {
        e.printStackTrace();
        stopRecord();
    }
}

//显示录像时长
private Runnable updateTimeRunnable = new Runnable() {
    @Override
    public void run() {
        if (second >= 59) {
            if (minute >= 59) {
                hour++;
                minute = 0;
            } else {
                minute++;
            }
            second = 0;
        } else {
            second++;
        }
        if (hour > 0) {
            tvTime.setText(String.format("%02d:%02d:%02d", hour, minute, second));
        } else {
            tvTime.setText(String.format("%02d:%02d", minute, second));
        }
        //录制超过最大时长
        if (new Date().getTime() - startRecordTime >= RECORDER_MAX_LENGTH) {
            stopRecord();
            return;
        }

        handler.postDelayed(this, 1000);
    }
}

//将位置信息写入字幕文件
private Runnable recordSrtRunnable = new Runnable() {
    @Override
    public void run() {
        StringBuilder srtBuilder = new StringBuilder();
        String srtTime = String.format("%02d:%02d:%02d,000", hour, minute, second);
        srtBuilder.append(srtRowNum++ + "\n");
        srtBuilder.append(String.format("%s --> %s\n", lastSrtTime, srtTime));
        srtBuilder.append(String.format("%s%.2f\n", "高程:", altitude));
        srtBuilder.append("\n");
        srtBuilder.append(srtRowNum++ + "\n");
        srtBuilder.append(String.format("%s --> %s\n", lastSrtTime, srtTime));
        srtBuilder.append(String.format("%s%s %s%s\n", "纬度:", latitude, "经度:", longitude));
        srtBuilder.append("\n");
        lastSrtTime = srtTime;

        File srtFile = new File(srtPath);
        try {
            FileOutputStream fs = new FileOutputStream(srtFile.getAbsolutePath(), true);
            fs.write(srtBuilder.toString().getBytes());
            fs.close();
        } catch (Exception e) {
            e.printStackTrack();
        }

        handler.postDelayed(this, srtInterval);
    }
}
  • stopRecord:停止录制,释放资源
private void stopRecord() {
    try {
        if (mediaRecorder != null) {
            handler.removeCallbacks(recordSrtRunnable);
            handler.removeCallbacks(updateTimeRunnable);
            mediaRecorder.stop();
            mediaRecorder.reset();
            mediaRecorder.release();
            mediaRecorder = null;
        }   
        if (camera != null) {
            camera.release();
            camera = null;
        }    
    } catch (Exception e) {
        e.printStackTrace();
    }
}

播放

  • startPlay:开始播放
private void startPlay() {
    if (mediaPlayer == null) {
        mediaPlayer = new MediaPlayer();
    }
    mediaPlayer.reset();
    Uri uri = Uri.parse(path);
    mediaPlayer = MediaPlayer.create(MainActivity.this, uri);
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mediaPlayer.setDisplay(surfaceHolder);
    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            stopPlay();
        }
    });
    try {
        mediaPlayer.prepare();
    } catch (Exception e) {
        e.printStackTrace();
    }
    mediaPlayer.start();
}
  • stopPlay:停止播放,释放资源
private void stopPlay() {
    if (mediaPlayer != null){
        mediaPlayer.stop();
        mediaPlayer.reset();
        mediaPlayer.release();
        mediaPlayer = null;
    }
}

其他

  • 判断闪光灯是否可用
getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
  • 开关闪光灯
btnFlash.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (isFlashOn) {
            btnFlash.setImageResource(R.drawable.video_flash_close);
            isFlashOn = false;
        } else {
            btnFlash.setImageResource(R.drawable.video_flash_on);
            isFlashOn = true;
        }
        cameraPara.setFlashMode(isFlashOn ? Parameters.FLASH_MODE_TORCH : Parameters.FLASH_MODE_OFF);
        camera.setParameters(cameraPara);
    }
});
  • AndroidManifest.xml添加权限
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • 字幕文件srt的格式
1
00:00:00,000 --> 00:00:01,000
高程:150.60

2
00:00:00,000 --> 00:00:01,000
纬度:22.982481666666665 经度:113.36807833333333

3
00:00:01,000 --> 00:00:02,000
高程:150.60

4
00:00:01,000 --> 00:00:02,000
纬度:22.982481666666665 经度:113.36807833333333
  • 录制结果

这里写图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值