现在大部分是视频网站都是用m3u8的形式播放视频。要注意的是其实m3u8本身并不是视频文件,而是一个视频文件的目录索引而已,它规定了分段视频的播放顺序,所以即使下载m3u8文件是不能直接播放视频的,那我们要怎么做才能得到可以直接播放过的视频文件呢?



现在大部分是视频网站都是用m3u8的形式播放视频。要注意的是其实m3u8本身并不是视频文件,而是一个视频文件的目录索引而已,它规定了分段视频的播放顺序,所以即使下载m3u8文件是不能直接播放视频的,那我们要怎么做才能得到可以直接播放过的视频文件呢?

安装ffmpeg

mac

brew install ffmpeg // 安装ffmpeg(可能报错无法连接外网资源)
curl -O https://evermeet.cx/ffmpeg/ffmpeg-4.4.zip //安装ffmpeg(直接官网下载ffmpeg-4.4,本地解压后的可执行文件直接使用)


linux

apt install ffmpeg


m3u8转mp4

远程的m3u8以mp4保存到本地

(本方法亲测过,推荐使用)

ffmpeg -i "https://xx.xx.com/xxxxxxxx/index.m3u8" -c copy ~/video/out.mp4


本地资源转mp4

(本方法没有全部测试完,建议自行测试下)

(需要注意有的m3u8文件中分段视频可能不是ts后缀结尾的,有的是可以直接改后缀名即可)

curl -O https://xxx.com/index.m3u8
sh ts_download.sh //执行ts文件下载脚本
sh ts_merge.sh //执行ts文件合并脚本,得到new.ts
ffmpeg -i new.ts -c:v copy -c:a libfaac out.mp4 //ts转mp4
ffmpeg -i new.ts -c:v libx264 -crf 24 -c:a libfaac out.mp4 //ts转mp4


ts_download.sh

while read myline
do

if [[ $myline =~ "http" ]]
then
# 下载所有ts文件
right=${myline##*/}
curl -o ts/${myline##*/} $myline
echo "LINE : ${right} "
else
continue
fi
done < index.m3u8


ts_merge.sh

all_str=""

while read myline
do

if [[ $myline =~ "http" ]]
then
# ts文件顺序(按index.m3u8的顺序合并,这里只读取文件名就好)
right=${myline##*/}
echo "LINE : ${right} "
all_str=$all_str" "${right}
else
continue
fi
done < index.m3u8

# 将多个ts文件合并成一个(eg: cat 111.ts 222.ts > new.ts)
touch new.ts
cd ts
cat $all_str > ../new.ts