更新记录
1.0.2(2024-06-16)
修改文件读取API失败函数的回调参数类型
1.0.1(2024-04-27)
增加对图片的编辑
1.0.0(2024-04-26)
初始化
查看更多
平台兼容性
App |
快应用 |
微信小程序 |
支付宝小程序 |
百度小程序 |
字节小程序 |
QQ小程序 |
HBuilderX 4.12,Android:7.0,iOS:不支持,HarmonyNext:不确定 |
× |
× |
× |
× |
× |
× |
钉钉小程序 |
快手小程序 |
飞书小程序 |
京东小程序 |
× |
× |
× |
× |
H5-Safari |
Android Browser |
微信浏览器(Android) |
QQ浏览器(Android) |
Chrome |
IE |
Edge |
Firefox |
PC-Safari |
× |
× |
× |
× |
× |
× |
× |
× |
× |
xwq-ffmpeg
文档说明
插件集成ffmpeg实现安卓端对视频、音频、图片的编辑功能
- 功能支持
- 视频裁剪
- 视频合并 (注:同种类型文件合并)
- 视频格式转换
- 音频合并 (注:同种类型文件合并)
- 音频格式转换
- 获取媒体信息
- 图片裁剪
- 图片格式转换
- 图片旋转
- ....更多功能可查阅官网
页面使用方式
<template>
<view>
<video :src="path" :autoplay="autoplay" :controls="true" :style="{height:'250px',width:'100%'}" :object-fit="objectFit" class="`video_1`" >
</video>
</view>
<view class="btn-wrap" :style="{marginBottom:'15px'}">
<button class="btn" @click='executeFFmpeg'>{{title}}</button>
<button class="btn" @click='videoMerge'>视频合并</button>
<button class="btn" @click='changeVideoType'>视频格式转换</button>
<button class="btn" @click='audioMerge'>音频合并</button>
<button class="btn" @click='changeAudioType'>音频格式转换</button>
<button class="btn" @click='getVideoInfo'>获取媒体信息</button>
<button class="btn" @click='imageRota'>图片旋转</button>
<button class="btn" @click='imageCrop'>图片裁剪</button>
<button class="btn" @click='getVideoInfo'>获取媒体信息</button>
</view>
<view class="content-wrap">
<text :style="{color:'red'}">媒体信息输出:</text>
<view class="content">
<textarea :value="content"></textarea>
</view>
</view>
<image :src="imagePath" :style="{width:'100%',height:'auto'}"></image>
</template>
<script setup>
import {useExecuteFFmpeg,
FfmpegType,
getMediaInfo,
getLocalPath,
TaskStartCallbackOpt,
StatisticsCallBackOpt,
ffmpegVideoMerge,
MergeType,
convertTypeV
} from '../../uni_modules/xwq-ffmpeg';
const title=ref('执行命令')
const objectFit='cover'
const autoplay=ref(false)
const content=ref('')
const imagePath=ref('')
const path=ref('/static/test002.mp4')
const executeFFmpeg=async ()=>{
// -vf "scale=1080x1080"
// libx265 mpeg4
let result=await getLocalPath('/static/test.mp4');
let outPath=`/storage/emulated/0/DCIM/Camera/video_${Date.now()}.mp4`
let cmd=`-i ${result} -c:v libx265 -s 540x280 -y ${outPath}`;
useExecuteFFmpeg({
cmd,
success:()=>{
console.log('成功回调====')
path.value=outPath
autoplay.value=true
},
cancel:()=>{
console.log('取消执行回调===')
},
fail:()=>{
console.log('失败回调====')
},
taskStart:(val:TaskStartCallbackOpt)=>{
console.log('任务开始回调===',val)
},
statistics:(val:StatisticsCallBackOpt)=>{
// console.log('统计信息开始回调===',val)
}
} as FfmpegType)
}
/**
*视频合并
*/
const videoMerge=async()=>{
let filePath=['/static/test.mp4','/static/test002.mp4']
let outPath=`/storage/emulated/0/DCIM/Camera/merge_video${Date.now()}.mp4`
ffmpegVideoMerge({
filePath,
outPath,
success:()=>{
path.value=outPath
autoplay.value=true
},
fail:()=>{
console.log('失败回调====')
}
} as MergeType)
}
//视频格式转换
const changeVideoType=()=>{
let inputPath='/static/test.mp4';
let videoType='flv';
let outPath=`/storage/emulated/0/DCIM/Camera/convertType${Date.now()}.${videoType}`;
convertTypeV(inputPath,videoType,outPath).then((filePath:string)=>{
path.value=filePath
autoplay.value=true
});
}
//音频合并
const audioMerge=()=>{
let filePath=['/static/test001.mp3','/static/test002.mp3']
// let filePath=['https://www.wanguoqiche.com/files/web/video/test001.mp4','https://www.wanguoqiche.com/files/web/video/test002.mp4']
let outPath=`/storage/emulated/0/Android/data/uni.UNI43B527F/files/merge_Audio${Date.now()}.mp3`
ffmpegVideoMerge({
type:2,
filePath,
outPath,
success:()=>{
// path.value=outPath
// autoplay.value=true
},
fail:()=>{
console.log('失败回调====')
}
} as MergeType)
}
//音频格式转换
const changeAudioType=()=>{
let inputPath='/static/test001.mp3';
let videoType='FLAC';
let outPath=`/storage/emulated/0/Android/data/uni.UNI43B527F/files/convertType${Date.now()}.${videoType}`;
convertTypeV(inputPath,videoType,outPath).then((filePath:string)=>{
console.log('音频filePath====',filePath)
});
}
//获取视频信息
const getVideoInfo=()=>{
let inputPath='/static/test.mp4'
// let inputPath='/storage/emulated/0/DCIM/Camera/video_1714100294515.mp4'
getMediaInfo(inputPath,(val:string)=>{
content.value=val
})
}
//图片格式转换
const changeImageType=async ()=>{
let inputPath=await getLocalPath('/static/logo.png');
let outPath=`/storage/emulated/0/DCIM/Camera/logo_${Date.now()}.jpg`
let cmd=`-i ${inputPath} ${outPath}`;
useExecuteFFmpeg({
cmd,
success:()=>{
console.log('成功回调====')
imagePath.value=outPath
}
} as FfmpegType)
}
//图片旋转
const imageRota=async ()=>{
let inputPath=await getLocalPath('/static/crop.png');
let outPath=`/storage/emulated/0/DCIM/Camera/logo_${Date.now()}.png`
let cmd=`-i ${inputPath} -vf "transpose=0" ${outPath}`;
// transpose=0:逆时针旋转 90 度。
// transpose=1:顺时针旋转 90 度。
// transpose=4,vflip:垂直翻转。
useExecuteFFmpeg({
cmd,
success:()=>{
console.log('成功回调====')
imagePath.value=outPath
}
} as FfmpegType)
}
//图片裁剪
const imageCrop=async ()=>{
let inputPath=await getLocalPath('/static/crop.png');
let outPath=`/storage/emulated/0/DCIM/Camera/crop_${Date.now()}.png`
let cmd=`-i ${inputPath} -vf "crop=300:200:0:0" ${outPath}`;
// crop=w:h:x:y
// w裁剪后的宽度
// h裁剪后的高
//x y 裁剪起点坐标
useExecuteFFmpeg({
cmd,
success:()=>{
console.log('成功回调====')
imagePath.value=outPath
}
} as FfmpegType)
}
</script>
<style>
.btn-wrap{
flex-direction: row;
flex-wrap: wrap;
padding: 10px;
justify-content: flex-start;
}
.btn{
margin: 0 10px 15px 0;
}
.content-wrap{
padding: 10px;
width: 100%;
min-height:100px;
}
.content{
width: 100%;
height: 100%;
border: 1px solid #ccc;
background-color: #f2f2f2;
}
</style>
调用方法说明
方法参数说明
属性 |
类型 |
描述 |
cmd |
string |
FFmpeg命令,可参照官网例子 |
success |
function |
成功回调 |
cancel |
function |
取消回调 |
fail |
function |
失败回调 |
taskStart |
function |
任务开始回调 |
statistics |
function |
统计信息回调 |
方法参数说明
属性 |
类型 |
描述 |
type |
number |
合并的文件类型 默认1 视频格式 ,可选2 音频格式 |
filePath |
string |
文件路径 只支持同种类型文件 |
outPath |
string |
文件输出路径 |
success |
function |
成功回调 |
fail |
function |
失败回调 |
方法参数说明
属性 |
类型 |
描述 |
inputPath |
string |
输入地址 |
outPath |
string |
输出地址 |
vType |
string |
要转换的视频类型 |
属性 |
类型 |
描述 |
filePath |
string |
文件地址 |
属性 |
类型 |
描述 |
sessionId |
number |
null |
会话ID,取消某个任务时需要传 |