• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import { media } from '@kit.MediaKit';
16import { BusinessError } from '@kit.BasicServicesKit';
17import { common } from '@kit.AbilityKit';
18import fs from '@ohos.file.fs';
19
20export class AVTranscoderDemo {
21  private avTranscoder: media.AVTranscoder | undefined = undefined;
22  private context: Context | undefined;
23  private currentProgress: number = 0;
24  constructor(context: Context | undefined) {
25    if (context != undefined) {
26      this.context = context;
27    }
28  }
29  private avConfig: media.AVTranscoderConfig = {
30    audioBitrate: 100000, // 音频比特率。
31    audioCodec: media.CodecMimeType.AUDIO_AAC, // 音频编码格式。
32    fileFormat: media.ContainerFormatType.CFT_MPEG_4, // 封装格式。
33    videoBitrate: 200000, // 视频比特率。
34    videoCodec: media.CodecMimeType.VIDEO_AVC, // 视频编码格式。
35  };
36
37  // 注册avTranscoder回调函数。
38  setAVTranscoderCallback() {
39    if (canIUse('SystemCapability.Multimedia.Media.AVTranscoder')) {
40      if (this.avTranscoder != undefined) {
41        // 转码完成回调函数。
42        this.avTranscoder.on('complete', async () => {
43          console.log(`AVTranscoder is completed`);
44          await this.releaseTranscoderingProcess();
45        });
46        // 错误上报回调函数。
47        this.avTranscoder.on('error', (err: BusinessError) => {
48          console.error(`AVTranscoder failed, code is ${err.code}, message is ${err.message}`);
49        });
50        // 进度上报回调函数
51        this.avTranscoder.on('progressUpdate', (progress: number) => {
52          console.info(`AVTranscoder progressUpdate = ${progress}`);
53          this.currentProgress = progress;
54        })
55      }
56    }
57  }
58
59  // 开始转码对应的流程。
60  async startTranscoderingProcess() {
61    if (canIUse('SystemCapability.Multimedia.Media.AVTranscoder')) {
62      if (this.avTranscoder != undefined) {
63        await this.avTranscoder.release();
64        this.avTranscoder = undefined;
65      }
66      // 1.创建转码实例。
67      this.avTranscoder = await media.createAVTranscoder();
68      this.setAVTranscoderCallback();
69      // 2.获取转码源文件fd和目标文件fd赋予avTranscoder;参考FilePicker文档。
70      if (this.context != undefined) {
71        try {
72          // 获取输入文件fd,H264_AAC.mp4为rawfile目录下的预置资源,需要开发者根据实际情况进行替换。
73          let fileDescriptor = await this.context.resourceManager.getRawFd('H264_AAC.mp4');
74          this.avTranscoder.fdSrc = fileDescriptor;
75        } catch (error) {
76          console.error('Failed to get the file descriptor, please check the resource and path.');
77        }
78        let outputFilePath = this.context.filesDir + '/output.mp4';
79        let file = fs.openSync(outputFilePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
80        this.avTranscoder.fdDst = file.fd;
81        this.currentProgress = 0;
82      }
83      // 3.配置转码参数完成准备工作。
84      await this.avTranscoder.prepare(this.avConfig);
85      // 4.开始转码。
86      await this.avTranscoder.start();
87    }
88  }
89
90  // 暂停转码对应的流程。
91  async pauseTranscoderingProcess() {
92    if (canIUse('SystemCapability.Multimedia.Media.AVTranscoder')) {
93      if (this.avTranscoder != undefined) { // 仅在调用start返回后调用pause为合理调用。
94        await this.avTranscoder.pause();
95      }
96    }
97  }
98
99  // 恢复对应的转码流程。
100  async resumeTranscoderingProcess() {
101    if (canIUse('SystemCapability.Multimedia.Media.AVTranscoder')) {
102      if (this.avTranscoder != undefined) { // 仅在调用pause返回后调用resume为合理调用。
103        await this.avTranscoder.resume();
104      }
105    }
106  }
107
108  // 释放转码流程。
109  async releaseTranscoderingProcess() {
110    if (canIUse('SystemCapability.Multimedia.Media.AVTranscoder')) {
111      if (this.avTranscoder != undefined) {
112        // 1.释放转码实例。
113        await this.avTranscoder.release();
114        this.avTranscoder = undefined;
115        // 2.关闭转码目标文件fd。
116        fs.closeSync(this.avTranscoder!.fdDst);
117      }
118    }
119  }
120
121  // 获取当前进度
122  getCurrentProgress(): number {
123    console.info(`getCurrentProgress = ${this.currentProgress}`);
124    return this.currentProgress;
125  }
126
127  // 一个完整的【开始转码-暂停转码-恢复转码-转码完成】示例。
128  async avTranscoderDemo() {
129    await this.startTranscoderingProcess(); // 开始转码。
130    await this.pauseTranscoderingProcess(); //暂停转码。
131    await this.resumeTranscoderingProcess(); // 恢复转码。
132  }
133}
134