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