【鸿蒙HarmonyOS Next实战开发】mp4parser库-音视频裁剪、合成、取帧等操作

mp4parser

简介

一个读取、写入操作音视频文件编辑的工具。

下载安装

ohpm install @ohos/mp4parser

OpenHarmony ohpm 环境配置等更多内容,请参考如何安装 OpenHarmony ohpm 包

使用说明

视频合成

  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 = 0that.imageHeight = 0if (code == 0) {AlertDialog.show({ message: $r('app.string.ok') })}else {AlertDialog.show({ message: $r('app.string.failed') })}}}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=0that.imageHeight=0if (code == 0) {AlertDialog.show({ message: $r('app.string.ok') })}else {AlertDialog.show({ message: $r('app.string.failed') })}}}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 = 0that.imageHeight = 0if (code == 0) {AlertDialog.show({ message: $r('app.string.ok') })}else {AlertDialog.show({ message: $r('app.string.failed') })}}}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 = 0that.imageHeight = 0if (code == 0) {AlertDialog.show({ message: $r('app.string.ok') })}else {AlertDialog.show({ message: $r('app.string.failed') })}}}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 = 0that.imageHeight = 0if (code == 0) {AlertDialog.show({ message: $r('app.string.ok') })}else {AlertDialog.show({ message: $r('app.string.failed') })}}}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 = 0that.imageHeight = 0if (code == 0) {AlertDialog.show({ message: $r('app.string.ok') })}else {AlertDialog.show({ message: $r('app.string.failed') })}}}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) DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release (5.0.0.66)

目录结构

|---- mp4parser  
|     |---- entry  # 示例代码文件夹
|     |---- library  # mp4parser库文件夹
|           |---- MP4Parser.ets  # 对外接口
|     |---- README.MD  # 安装使用方法                    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/69719.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Maven 中常用的 scope 类型及其解析

在 Maven 中,scope 属性用于指定依赖项的可见性及其在构建生命周期中的用途。不同的 scope 类型能够影响依赖项的编译和运行阶段。以下是 Maven 中常用的 scope 类型及其解析: compile(默认值): 这是默认的作用域。如果…

redis项目

短信登录 这一块我们会使用redis共享session来实现 商户查询缓存 通过本章节,我们会理解缓存击穿,缓存穿透,缓存雪崩等问题,让小伙伴的对于这些概念的理解不仅仅是停留在概念上,更是能在代码中看到对应的内容 优惠…

瑞友天翼应用虚拟化系统 GetPwdPolicy SQL注入漏洞复现

免责声明 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在使…

android设置添加设备QR码信息

摘要:客户衍生需求,通过扫QR码快速获取设备基础信息,并且基于POS SDK进行打印。 1. 定位至device info的xml添加相关perference Index: vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/my_device_info.xml--- vendor/medi…

Ubuntu 多版本 gcc 配置常用命令备忘

用的频率不高,总忘记具体参数 1,安装多版本 gcc 以 gcc-11 和12 为例: sudo apt-get install gcc-11 gcc-12 sudo apt-get install gcc-11 gcc-12 2,配置多版本 gcc gcc 与 g 一起配置进数据库中: sudo update-a…

【kubernetes组件合集】深入解析Kubernetes组件之三:client-go

深入解析Kubernetes组件之三:client-go 目录 深入解析Kubernetes组件之三:client-go 引言 1. client-go简介 2. client-go的功能 2.1 资源操作 2.2 资源监听 2.3 认证和授权 2.4 错误处理和重试 2.5 扩展性和定制化 3. 使用client-go与Kubern…

数据结构——【二叉树模版】

#思路 1、二叉树不同于数的构建,在树节点类中,有数据,左子结点,右子节点三个属性,在树类的构造函数中,添加了变量maxNodes,用于后续列表索引的判断 2.GetTreeNode()函数是常用方法,…

【ubuntu下验证下菜品识别,训练,部署,验证 CNN + TensorFlow / PyTorch】

下来我会详细介绍如何在 Ubuntu 上运行你训练和部署的 菜品识别模型,确保每一步都能理解并能在你的系统中运行。 环境准备 1.1 安装必要的软件 在 Ubuntu 上,首先需要安装 Python 和相关的依赖库:更新系统: 打开终端,运行以下命令: bash sudo apt update && su…

多项式插值(数值计算方法)Matlab实现

多项式插值(数值计算方法)Matlab实现 一. 原理介绍二. 程序设计1. 构建矩阵2. 求解矩阵方程3. 作出多项式函数4. 绘制插值曲线5. 完整代码 三. 图例 一. 原理介绍 关于插值的定义及基本原理可以参照如下索引 插值原理(数值计算方法&#xff…

【Python深入浅出㉙】Python3邂逅MySQL:开启数据交互之旅

目录 一、Python 与 MySQL 的 “牵手” 前奏二、准备工作:搭建 “舞台”三、建立连接:开启沟通桥梁(一)pymysql 连接示例(二)mysql-connector 连接示例 四、基本操作:数据库的 “增删改查”&…

vite + axios 代理不起作用 404 无效

vite axios 代理不起作用 先看官方示例 export default defineConfig({server: {proxy: {// 字符串简写写法/foo: http://localhost:4567,// 选项写法/api: {target: http://jsonplaceholder.typicode.com,changeOrigin: true,rewrite: (path) > path.replace(/^\/api/, )…

【Elasticsearch】Elasticsearch检索方式全解析:从基础到实战(一)

文章目录 引言Elasticsearch检索方式概述两种检索方式介绍方式一:通过REST request uri发送搜索参数方式二:通过REST request body发送搜索参数(1)基本语法格式(2)返回部分字段(3)ma…

我准备做一个24H的摄像机模拟器,用录像视频模拟实时画面,如果能支持时间水印就更好了

之前我不是搞了一个摄像机模拟器吗《用EasyRTSPServer模拟摄像机RTSP流实现RTSP摄像机模拟器 》,搞的比较简单,就是用视频文件模拟摄像机的画面,那个只能简单用来做个IPC模拟,给开发者用用或者给调研的人看看可行性,实…

冒泡排序

目录 冒泡排序: 代码实现&#xff1a; 思路分析&#xff1a; 冒泡排序优化&#xff1a; 冒泡排序&#xff08;稳定&#xff09;: 想要数据从小到大排序。 代码实现&#xff1a; public static void bubbleSort(int[] arr) {//趟数for (int i 0; i < arr.length - 1; i) {…

国产编辑器EverEdit - 编辑辅助功能介绍

1 编辑辅助功能 1.1 各编辑辅助选项说明 1.1.1 行号 打开该选项时&#xff0c;在编辑器主窗口左侧显示行号&#xff0c;如下图所示&#xff1a; 1.1.2 文档地图 打开该选项时&#xff0c;在编辑器主窗口右侧靠近垂直滚动条的地方显示代码的缩略图&#xff0c;如下图所示&…

深入理解Java对接DeepSeek

其实&#xff0c;整个对接过程很简单&#xff0c;就四步&#xff0c;获取key&#xff0c;找到接口文档&#xff0c;接口测试&#xff0c;代码对接。 1.获取 KEY https://platform.deepseek.com/transactions 直接付款就是了&#xff08;现在官网暂停充值2025年2月7日&#xf…

调用DeepSeek官方的API接口

效果 前端样式体验链接&#xff1a;https://livequeen.top/deepseekshow 准备工作 1、注册deepseek官网账号 地址&#xff1a;DeepSeek 点击进入右上角【API开放平台】&#xff0c;并进行账号注册。 2、注册完成后&#xff0c;依次点击【API keys】-【生成API key】&#x…

【SpringBoot实现全局API限频】 最佳实践

在 Spring Boot 中实现全局 API 限频&#xff08;Rate Limiting&#xff09;可以通过多种方式实现&#xff0c;这里推荐一个结合 拦截器 Redis 的分布式解决方案&#xff0c;适用于生产环境且具备良好的扩展性。 方案设计思路 核心目标&#xff1a;基于客户端标识&#xff08…

香港中文大学 Adobe 推出 MotionCanvas:开启用户掌控的电影级图像视频创意之旅。

简介&#xff1a; 亮点直击 将电影镜头设计引入图像到视频的合成过程中。 推出了MotionCanvas&#xff0c;这是一种简化的视频合成系统&#xff0c;用于电影镜头设计&#xff0c;提供整体运动控制&#xff0c;以场景感知的方式联合操控相机和对象的运动。 设计了专门的运动条…

01.Docker 概述

Docker 概述 1. Docker 的主要目标2. 使用Docker 容器化封装应用程序的意义3. 容器和虚拟机技术比较4. 容器和虚拟机表现比较5. Docker 的组成6. Namespace7. Control groups8. 容器管理工具9. docker 的优缺点10. 容器的相关技术 docker 官网: http://www.docker.com 帮助文档…