1. 创建合并文件脚本 vmerger
移动所有子文件夹中.mp4文件到目录下
find ./ -name "*.mp4" | xargs -I file mv file ./
使用ls:无法指定mp4文件类型
ls | awk '{print "file '\''" $7 "'\''"}' > vmerger.txt
使用find:排序不太准
find . -type f -name "*.mp4" | sort | awk '{sub(/\.\//,""); print "file '\''" $1 "'\''"}' > vmerger
2. 合并视频
ffmpeg -f concat -safe 0 -i vmerger -c copy output.mp4
3. 倍速视频(1.25倍速:v反向0.8,a正向1.25)
ffmpeg -i output.mp4 -filter_complex "[0:v]setpts=0.8*PTS[v];[0:a]atempo=1.25[a]" -map "[v]" -map "[a]" outputX.mp4
4. 创建章节时间点信息(注意命名不能出现空格)
echo 'l=$(ffmpeg -i $1 2>&1 | grep 'Duration' | cut -d "'" "'" -f 4 | sed s/,//);echo "${1:2} ${l:0:8}"' > ./ff
chmod +x ./ff
find . -type f -name "*.mp4" | sort | awk '{system("./ff " $1)}' > time.txt
5. 知识点总结(选看)
1、shell中echo使用单引号时输出单引号
[root@db01 ~] echo 'hello'"'"'world'
hello'world
2、Shell字符串截取(非常详细)
| 格式 | 说明 |
|---|---|
| ${string:start:length} | 从string字符串的左边第start个字符开始,向右截取length个字符 |
| ${string:start} | 从string字符串的左边第start个字符开始截取,直到最后 |
| ${string:0-start:length} | 从string字符串的右边第start个字符开始,向右截取length个字符 |
| ${string:0-start} | 从string字符串的右边第start个字符开始截取,直到最后 |
| ${string#*chars} | 从string字符串第一次出现chars的位置开始,截取chars右边的所有字符 |
| ${string##*chars} | 从string字符串最后一次出现chars的位置开始,截取chars右边的所有字符 |
| ${string%chars*} | 从string字符串第一次出现chars的位置开始,截取chars左边的所有字符 |
| ${string%%chars*} | 从string字符串最后一次出现chars的位置开始,截取chars左边的所有字符 |
3、awk输出单引号,双引号
双引号:
awk '{print "\""}' #放大:awk '{print " \" "}'
使用“”双引号把一个双引号括起来,然后用转义字符\对双引号进行转义,输出双引号。
单引号:
awk '{print "'\''"}' # 放大: awk '{print " ' \ ' ' " }'
使用一个双引号“”,然后在双引号里面加入两个单引号‘’,接着在两个单引号里面加入一个转义的单引号',输出单引号。
4、在awk中执行system命令------太有用了
有这样一个临时需求: 在a.txt文件中有一万行字符串, 而二进制文件test能解密任何一行, 格式为./test decrypt xxx, 现在要把a.txt的所有行解密出来, 存放在b.txt, 怎么搞?
我一开始的思路是: 写程序逐行读取a.txt, 然后在程序中循环执行system("./test decrypt xxx"), 看看, 这是多个SB的事情啊。 为什么不用awk + system快速搞起呢?
ubuntu@VM-0-13-ubuntu:~$ cat a.txt
abc
def
ok
ubuntu@VM-0-13-ubuntu:~$ awk '{cmd="echo hehe "$0; system(cmd)}' a.txt
hehe abc
hehe def
hehe ok
ubuntu@VM-0-13-ubuntu:~$
所以, 在我那个实际例子, 可以这么搞:
awk '{cmd="./test decrypt "$0; system(cmd)}' a.txt > b.txt
本来以为要半个小时, 结果5分钟搞定。
5、awk substr 左、右取字符
从左截取参考:
substr($4,20) ---> 表示是从第4个字段里的第20个字符开始,一直到设定的分隔符","结束.
substr($3,12,8) ---> 表示是从第3个字段里的第12个字符开始,截取8个字符结束.
#示例:
$echo "this is a test,test" |awk -F',' '{print substr($1,1,4)"," substr($2,1) } ' //以,为分隔符,取第一子串的从第一个字符开始的4个字符和第二子串的第一个字符开始的全部字符,且以“,”分割符打印输出
this,test
从右截取参考:
awk '{print substr($0,1,length($0)-4)}' //表示对整个字符串,取去掉自右开始的4个字符后的字符串
# 示例:
$echo "this is a test,test" |awk '{print substr($0,1,length($0)-4)}'
this is a test,
$echo "this is a test,test" |awk -F, '{print substr($1,length($1)-0)}' //取自右开始的第一个字符
t
$echo "this is a test,test" |awk -F, '{print substr($1,length($1)-1)}' //取自右开始的前两个字符
st
$echo "this is a test,test"|awk '{print length($0)}' // 获取字符串长度
带有目录的字符串
$echo 'z:\testPath\te_120200\' | awk '{print length($0)}' //双引号和不加引号都不能达到识别字符串的目的
6、不使用 ffmpeg 命令读取mp4视频时长
大家一般都用 ffmpeg 获取视频长度,今天看到有一个 mediainfo 也有这个功能。
ffmpeg 命令是
ffmpeg -i test.flv 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//
#或者
ffprobe -v quiet -select_streams v -show_entries stream=duration -of csv=“p=0” foo.mp4
视频的时长有多个值,分别是容器时长、音视频流时长、解码后播放时长,这几个值可能不一样,就导致了不同播放器显示值不一样,不同播放时也因此表现得不一样。如果发现容器或流的持续时间丢失或不准确(可能由于文件损坏或被截断),则可能需要完全解码输入。
centos 7 安装 mediainfo
yum install mediainfo -y
MacOS 安装 mediainfo
brew install mediainfo
mediainfo 将以毫秒为单位的持续时间输出为单个整数值。
mediainfo --Output='General;%Duration%' file.mp4
批量查找目录下所有mp4 文件并打印时长
#!/bin/sh
echo 'l=$(mediainfo --Output="General;%Duration%" $1);echo "$1:$l"' > ~/ff
chmod +x ~/ff
find . -type f -name "*.mp4" | awk '{system("~/ff " $1)}'
7、以下FFmpeg命令我都实际操作可用,拿去使用改下名称即可
合并视频 vfilelist是文本文件,格式如图,将output.mp4追加合并后输出为 outlast.mp4 
ffmpeg -f concat -i vfilelist -c copy outlast.mp4
wav音频转为mp3
ffmpeg -i input.m4a output.mp3
2个音频合并
ffmpeg -i 音频1.mp3 -i 音频2.mp3 -filter_complex '[0:0] [1:0] concat=n=2:v=0:a=1 [a]' -map [a] result.mp3
3个音频合并
ffmpeg -i 音频1.wav -i 音频2.WAV -i 音频3.wav -filter_complex '[0:0] [1:0] [2:0] concat=n=3:v=0:a=1 [a]' -map [a] mresult.wav
ffmpeg -i fenweikong.mp3 -i fenweikong.mp3 -i fenweikong.mp3 -filter_complex '[0:0] [1:0] [2:0] concat=n=3:v=0:a=1 [a]' -map [a] mresult.mp3
合并音频和视频,复制音频(需要重新编码)
ffmpeg -i 视频.mp4 -i 音频.mp3 -c:v copy -c:a aac -strict experimental mvresult.mp4