video-recorder.md 5.1 KB
Newer Older
1 2 3 4 5 6
# 视频录制开发指导

## 场景介绍

视频录制的主要工作是捕获音视频信号,完成音视频编码并保存到文件中,帮助开发者轻松实现音视频录制功能。它允许调用者指定录制的编码格式、封装格式、文件路径等参数。

Z
zengyawen 已提交
7
**图1** 视频录制状态机
8

Z
zengyawen 已提交
9
![zh-ch_image_video_recorder_state_machine](figures/zh-ch_image_video_recorder_state_machine.png)
10

Z
zengyawen 已提交
11

12 13 14

**图2** 视频录制零层图

Z
zengyawen 已提交
15
![zh-ch_image_video_recorder_zero](figures/zh-ch_image_video_recorder_zero.png)
16

Z
zengyawen 已提交
17
## 开发步骤
18 19 20 21 22 23 24 25

详细API含义可参考:[js-apis-media.md](../reference/apis/js-apis-media.md)

### 全流程场景

包含流程:创建实例,设置录制参数,录制视频,暂停录制,恢复录制,停止录制,释放资源等流程。

```js
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
import media from '@ohos.multimedia.media'
import mediaLibrary from '@ohos.multimedia.mediaLibrary'

let testFdNumber;

// pathName是传入的录制文件名,例如:01.mp4
// 使用mediaLibrary需要添加以下权限, ohos.permission.MEDIA_LOCATION、ohos.permission.WRITE_MEDIA、ohos.permission.READ_MEDIA
async function getFd(pathName) {
    let displayName = pathName;
    const mediaTest = mediaLibrary.getMediaLibrary();
    let fileKeyObj = mediaLibrary.FileKey;
    let mediaType = mediaLibrary.MediaType.VIDEO;
    let publicPath = await mediaTest.getPublicDirectory(mediaLibrary.DirectoryType.DIR_VIDEO);
    let dataUri = await mediaTest.createAsset(mediaType, displayName, publicPath);
    if (dataUri != undefined) {
        let args = dataUri.id.toString();
        let fetchOp = {
            selections : fileKeyObj.ID + "=?",
            selectionArgs : [args],
        }
        let fetchFileResult = await mediaTest.getFileAssets(fetchOp);
        let fileAsset = await fetchFileResult.getAllObject();
        let fdNumber = await fileAsset[0].open('Rw');
        fdNumber = "fd://" + fdNumber.toString();
        testFdNumber = fdNumber;
    }
}

await getFd('01.mp4');

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
let videoProfile = {
    audioBitrate : 48000,
    audioChannels : 2,
    audioCodec : 'audio/mp4a-latm',
    audioSampleRate : 48000,
    fileFormat : 'mp4',
    videoBitrate : 48000,
    videoCodec : 'video/mp4v-es',
    videoFrameWidth : 640,
    videoFrameHeight : 480,
    videoFrameRate : 30
}

let videoConfig = {
    audioSourceType : 1,
    videoSourceType : 0,
    profile : videoProfile,
73
    url : testFdNumber, // testFdNumber由getFd生成
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
    orientationHint : 0,
    location : { latitude : 30, longitude : 130 },
}
	
// 当发生错误上上报的错误回调接口
function failureCallback(error) {
    console.info('error happened, error name is ' + error.name);
    console.info('error happened, error code is ' + error.code);
    console.info('error happened, error message is ' + error.message);
}
	
// 当发生异常时,系统调用的错误回调接口
function catchCallback(error) {
    console.info('catch error happened, error name is ' + error.name);
    console.info('catch error happened, error code is ' + error.code);
    console.info('catch error happened, error message is ' + error.message);
}
	
let videoRecorder = null; // videoRecorder空对象在createVideoRecorder成功后赋值
let surfaceID = null; // 用于保存getInputSurface返回的surfaceID
94

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
// 创建videoRecorder对象
await media.createVideoRecorder().then((recorder) => {
    console.info('case createVideoRecorder called');
    if (typeof (recorder) != 'undefined') {
        videoRecorder = recorder;
        console.info('createVideoRecorder success');
    } else {
        console.info('createVideoRecorder failed');
    }
}, failureCallback).catch(catchCallback);

// 获取surfaceID并保存下来传递给camera相关接口
await videoRecorder.getInputSurface().then((surface) => {
    console.info('getInputSurface success');
    surfaceID = surface;
}, failureCallback).catch(catchCallback);
	
// 视频录制依赖相机相关接口,以下需要先调用相机起流接口后才能继续执行

// 视频录制启动接口
await videoRecorder.start().then(() => {
    console.info('start success');
}, failureCallback).catch(catchCallback);

// 调用pause接口时需要暂停camera出流
await videoRecorder.pause().then(() => {
    console.info('pause success');
}, failureCallback).catch(catchCallback);

// 调用resume接口时需要恢复camera出流
await videoRecorder.resume().then(() => {
    console.info('resume success');
}, failureCallback).catch(catchCallback);

// 停止camera出流后,停止视频录制
await videoRecorder.stop().then(() => {
    console.info('stop success');
}, failureCallback).catch(catchCallback);

// 重置录制相关配置
await videoRecorder.reset().then(() => {
    console.info('reset success');
}, failureCallback).catch(catchCallback);

// 释放视频录制相关资源并释放camera对象相关资源
await videoRecorder.release().then(() => {
    console.info('release success');
}, failureCallback).catch(catchCallback);

// 相关对象置null
videoRecorder = null;
surfaceID = null;
```