• 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 { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
16import { media } from '@kit.MediaKit';
17import { BusinessError } from '@kit.BasicServicesKit';
18import fs from '@ohos.file.fs';
19import { SendableObject } from '../util/SendableObject';
20import { common, sendableContextManager } from '@kit.AbilityKit';
21
22const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
23
24workerPort.onmessage = async (event: MessageEvents) => {
25  console.info(`onmessage in`);
26  //worker线程接收参数
27  const sendableObject: SendableObject = event.data;
28  const sendableContext: sendableContextManager.SendableContext =
29    sendableObject.getSendableContext() as sendableContextManager.SendableContext;
30  const context: common.Context =
31    sendableContextManager.convertToContext(sendableContext) as common.Context;
32  //执行转码逻辑
33  await doSome(context);
34  // 向主线程发送消息
35  workerPort.postMessage('start end');
36};
37
38workerPort.onmessageerror = (event: MessageEvents) => {
39  console.info('workerPort onmessageerror');
40};
41
42workerPort.onerror = (event: ErrorEvent) => {
43  console.info('workerPort onerror err is: ', event.message);
44};
45
46async function doSome(context: common.Context) {
47  console.info(`doSome in`);
48  try {
49    let transcoder = await media.createAVTranscoder();
50    // 转码完成回调函数
51    transcoder.on('complete', async () => {
52      console.info(`transcode complete`);
53      fs.closeSync(transcoder.fdDst);
54      await transcoder?.release()
55      // 向主线程发送转码结束的消息
56      workerPort.postMessage('complete');
57    })
58    // 转码错误回调函数
59    transcoder.on('error', async (err: BusinessError) => {
60      fs.closeSync(transcoder.fdDst);
61      await transcoder?.release();
62    })
63    // 转码进度更新
64    transcoder.on('progressUpdate', (progress: number) => {
65      console.info(`AVTranscoder progressUpdate = ${progress}`);
66      workerPort.postMessage(progress);
67    })
68    try {
69      // 获取输入文件fd,3.mkv为rawfile目录下的预置资源,需要开发者根据实际情况进行替换。
70      let fileDescriptor = await context.resourceManager.getRawFd('H264_AAC.mp4');
71      transcoder.fdSrc = fileDescriptor;
72    } catch (error) {
73      console.error('Failed to get the file descriptor, please check the resource and path.');
74    }
75    let fdPath = context.filesDir + '/' + 'VID_' + Date.parse(new Date().toString()) + '.mp4';
76    let file = fs.openSync(fdPath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
77    let fd = file.fd;
78    console.info(`file fd ${fd}`);
79    transcoder.fdDst = file.fd;
80
81    let config: media.AVTranscoderConfig = {
82      fileFormat: media.ContainerFormatType.CFT_MPEG_4,
83      audioCodec: media.CodecMimeType.AUDIO_AAC,
84      videoCodec: media.CodecMimeType.VIDEO_AVC,
85      videoBitrate: 200000,
86    }
87    await transcoder?.prepare(config);
88    await transcoder?.start();
89  } catch (e) {
90    console.error(`transcode error: code = ` + e.code.toString() + `, message = ${JSON.stringify(e.message)}`);
91  }
92}
93