# mp4parser **Repository Path**: longfeng20/mp4parser ## Basic Information - **Project Name**: mp4parser - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 35 - **Created**: 2024-06-29 - **Last Updated**: 2024-07-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mp4parser ## 简介 > 一个读取、写入操作音视频文件编辑的工具。 ## 编译运行 1、通过IDE工具下载依赖SDK,Tools->SDK Manager->Openharmony SDK 把native选项勾上下载,API版本>=10 2、开发板选择RK3568,[ROM下载地址](http://ci.openharmony.cn/workbench/cicd/dailybuild/dailylist). 选择开发板类型是rk3568,请使用最新的版本 3、下载源码 ``` git clone https://gitee.com/openharmony-tpc/mp4parser.git --recurse-submodules ``` 4、项目依赖FFmpeg库,关于FFmpeg的编译:[FFmpeg源码基于版本号:n4.2.5](https://github.com/FFmpeg/FFmpeg). ## FFmpeg依赖 1、修改编译之前需要在交叉编译中支持编译x86_64架构,可以参考[adpater_architecture.md](https://gitee.com/openharmony-sig/tpc_c_cplusplus/blob/master/docs/adpater_architecture.md)文档。 2、FFmpeg:FFmpeg版本(n4.2.5):[FFmpeg源码链接](https://github.com/bilibili/FFmpeg/tags), 可以在交叉编译出库文件和头文件 ​ 编译之前需要先修改HPKBUILD文件中[FFmpeg](https://gitee.com/openharmony-sig/tpc_c_cplusplus/tree/master/thirdparty/FFmpeg)的版本为n4.2.5。 ``` pkgver=n6.0 //修改为 pkgver=n4.2.5 ``` 3.下载FFmpeg的[n4.2.5](https://codeload.github.com/FFmpeg/FFmpeg/zip/refs/tags/n4.2.5),执行以下命令获取对应的sha512值,替换SHA512SUM文件的内容。 ``` sha512num FFmpeg-n4.2.5.zip ``` 4.在cpp目录下新增thirdparty目录,并将编译生成的库拷贝到该目录下,如下图所示 ![img.png](img/img.png) ## 下载安装 ```shell ohpm install @ohos/mp4parser ``` OpenHarmony ohpm 环境配置等更多内容,请参考[如何安装 OpenHarmony ohpm 包](https://gitee.com/openharmony-tpc/docs/blob/master/OpenHarmony_har_usage.md) ## X86模拟器配置 [使用模拟器运行应用/服务](https://developer.huawei.com/consumer/cn/deveco-developer-suite/enabling/kit?currentPage=1&pageSize=100) ## 使用说明 ### 视频合成 ``` import {MP4Parser} from "@ohos/mp4parser"; import {ICallBack} from "@ohos/mp4parser"; /** * 视频合成 */ private videoMerge() { let getLocalDirPath = getContext(this).cacheDir+"/"; let that = this; let filePathOne = getLocalDirPath + "qqq.mp4"; let filePathTwo = getLocalDirPath + "www.mp4"; let outMP4 = getLocalDirPath + "mergeout.mp4"; var callBack: ICallBack = { callBackResult(code: number) { that.btnText = "视频合成点击执行" that.imageWidth = 0 that.imageHeight = 0 if (code == 0) { AlertDialog.show({ message: '执行成功' }) } else { AlertDialog.show({ message: '执行失败' }) } } } MP4Parser.videoMerge(filePathOne, filePathTwo, outMP4, callBack); } ``` ### 视频裁剪 ``` import {MP4Parser} from "@ohos/mp4parser"; import {ICallBack} from "@ohos/mp4parser"; /** * 视频裁剪 */ private videoClip() { let getLocalDirPath = getContext(this).cacheDir+"/"; let that=this; let sTime = "00:00:10"; let eTime = "00:00:20"; let sourceMP4 = getLocalDirPath+"qqq.mp4"; let outMP4 = getLocalDirPath+"clipout.mp4"; var callBack: ICallBack = { callBackResult(code: number) { that.btnText="视频裁剪点击执行" that.imageWidth=0 that.imageHeight=0 if (code == 0) { AlertDialog.show({ message: '执行成功' }) } else { AlertDialog.show({ message: '执行失败' }) } } } MP4Parser.videoClip(sTime, eTime, sourceMP4, outMP4, callBack); } ``` ### 音频合成 ``` import {MP4Parser} from "@ohos/mp4parser"; import {ICallBack} from "@ohos/mp4parser"; /** * 音频合成 */ private audioMerge() { let getLocalDirPath = getContext(this).cacheDir+"/"; let that = this; let filePathOne = getLocalDirPath + "a.mp3"; let filePathTwo = getLocalDirPath + "b.mp3"; let outPath = getLocalDirPath + "mergeout.mp3"; var callBack: ICallBack = { callBackResult(code: number) { console.log("mp4parser-->audioMerge--->end"); that.btnText = "音频合成点击执行" that.imageWidth = 0 that.imageHeight = 0 if (code == 0) { AlertDialog.show({ message: '执行成功' }) } else { AlertDialog.show({ message: '执行失败' }) } } } MP4Parser.audioMerge(filePathOne, filePathTwo, outPath, callBack); } ``` ### 音频裁剪 ``` import {MP4Parser} from "@ohos/mp4parser"; import {ICallBack} from "@ohos/mp4parser"; /** * 音频裁剪 */ private audioClip() { let getLocalDirPath = getContext(this).cacheDir+"/"; let that = this; let sTime = "00:00:00"; let eTime = "00:00:10"; let sourcePath = getLocalDirPath + "a.mp3"; let outPath = getLocalDirPath + "clipout.mp3"; var callBack: ICallBack = { callBackResult(code: number) { that.btnText = "音频裁剪点击执行" that.imageWidth = 0 that.imageHeight = 0 if (code == 0) { AlertDialog.show({ message: '执行成功' }) } else { AlertDialog.show({ message: '执行失败' }) } } } MP4Parser.audioClip(sTime, eTime, sourcePath, outPath, callBack); } ``` ### 视频批量合成 ``` import {MP4Parser} from "@ohos/mp4parser"; import {ICallBack} from "@ohos/mp4parser"; /** * 视频批量合成 */ private videoMultMerge() { let that = this; let getLocalDirPath = getContext(this).cacheDir+"/"; let filePath = getLocalDirPath + "mergeList.txt"; let outMP4 = getLocalDirPath + "mergeout3.mp4"; var callBack: ICallBack = { callBackResult(code: number) { that.btnText2 = "视频合成点击执行" that.imageWidth = 0 that.imageHeight = 0 if (code == 0) { AlertDialog.show({ message: '执行成功' }) } else { AlertDialog.show({ message: '执行失败' }) } } } MP4Parser.videoMultMerge(filePath, outMP4, callBack); } ``` ### 音频批量合成 ``` import {MP4Parser} from "@ohos/mp4parser"; import {ICallBack} from "@ohos/mp4parser"; /** * 音频批量合成 */ private audioMultMerge() { let getLocalDirPath = getContext(this).cacheDir+"/"; let that = this; let filePath = getLocalDirPath + "mergewavList.txt"; let outPath = getLocalDirPath + "mergeout3.wav"; var callBack: ICallBack = { callBackResult(code: number) { that.btnText2 = "音频合成点击执行" that.imageWidth = 0 that.imageHeight = 0 if (code == 0) { AlertDialog.show({ message: '执行成功' }) } else { AlertDialog.show({ message: '执行失败' }) } } } MP4Parser.audioMultMerge(filePath, outPath, callBack); } ``` ### 视频取帧 ``` import {ICallBack, IFrameCallBack, MP4Parser} from "@ohos/mp4parser"; private getFrameAtTimeRang() { let getLocalDirPath = getContext(this).cacheDir + "/"; let sourceMP4 = getLocalDirPath + "www.mp4"; let that = this; var callBack: ICallBack = { callBackResult(code: number) { if (code == 0) { var frameCallBack: IFrameCallBack = { async callBackResult(data: ArrayBuffer, timeUs: number) { const imageSource = image.createImageSource(data) that.imagePixelMap = await imageSource.createPixelMap() } } MP4Parser.getFrameAtTimeRang("1000000", "9000000", MP4Parser.OPTION_CLOSEST, frameCallBack); } } } MP4Parser.setDataSource(sourceMP4, callBack); } ``` ### 调用FFmpeg指令 ``` let context = AbilityDelegatorRegistry.getAbilityDelegator().getAppContext() let getLocalDirPath = context.cacheDir + "/"; let sTime = "00:00:01"; let eTime = "00:00:02"; let sourceMP4 = getLocalDirPath + "testvideo.mp4"; let outMP4 = getLocalDirPath + "out.mp4"; let callBack: ICallBack = { callBackResult(code: number) { expect(0).assertEqual(code) done() } } MP4Parser.ffmpegCmd("ffmpeg -y -i " + sourceMP4 + " -ss " + sTime + " -c copy -to " + eTime + " " + outMP4, callBack) ``` ## 接口说明 `import {MP4Parser} from "@ohos/mp4parser";` 1. 视频合成 `MP4Parser.videoMerge()` 2. 视频裁剪 `MP4Parser.videoClip()` 3. 批量视频合成 `MP4Parser.videoMultMerge()` 4. 音频合成 `MP4Parser.audioMerge()` 5. 音频裁剪 `MP4Parser.audioClip()` 6. 音频批量合成 `MP4Parser.audioMultMerge()` 7. 设置视频源 `MP4Parser.setDataSource()` 8. 视频取帧 `MP4Parser.getFrameAtTimeRang()` 9. 停止取帧 `MP4Parser.stopGetFrame()` 10. 调用FFmpeg指令 `MP4Parser.ffmpegCmd()` ## 约束与限制 在下述版本验证通过: DevEco Studio版本: 4.0 Release(4.0.3.413), SDK: (4.0.10.3) DevEco Studio 版本: 4.1 Canary(4.1.3.317),OpenHarmony SDK: API11 (4.1.0.36) ## 目录结构 ```` |---- mp4parser | |---- entry # 示例代码文件夹 | |---- library # mp4parser库文件夹 | |---- MP4Parser.ets # 对外接口 | |---- README.MD # 安装使用方法 ```` ## 贡献代码 使用过程中发现任何问题都可以提 [Issue](https://gitee.com/openharmony-tpc/mp4parser/issues) 给我们,当然,我们也非常欢迎你给我们发 [PR](https://gitee.com/openharmony-tpc/mp4parser/pulls) 。 ## 开源协议 本项目基于 [Apache License 2.0](https://gitee.com/openharmony-tpc/mp4parser/blob/master/LICENSE) ,请自由地享受和参与开源。