m3u8格式转mp4
例如现有一个m3u8格式的视频地址:https://rescdn.yishihui.com/longvideo/videocomposite/output/live/696380/1583998162597time-1LD.m3u8?Expires=1585381145&OSSAccessKeyId=LTAIHZz0zdTMC7HN&Signature=nrihRPuLby7Lm8F92P3NtoXdlIo%3D,需要下载为mp4格式,解决思路:
通过m3u8格式的视频地址下载m3u8文件,文档编辑模式打开下载下来的m3u8文件,里面有所有ts文件,上面地址下载的m3u8文件打开是这样的:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:19
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:18.640000,
1583998162597time-1LD-00001.ts
#EXTINF:10.000000,
1583998162597time-1LD-00002.ts
#EXTINF:8.400000,
1583998162597time-1LD-00003.ts
#EXTINF:10.000000,
1583998162597time-1LD-00004.ts
#EXTINF:10.000000,
1583998162597time-1LD-00005.ts
#EXTINF:10.000000,
1583998162597time-1LD-00006.ts
#EXTINF:10.000000,
1583998162597time-1LD-00007.ts
#EXTINF:7.200000,
1583998162597time-1LD-00008.ts
#EXTINF:10.000000,
1583998162597time-1LD-00009.ts
#EXT-X-ENDLIST
上面只有ts的文件名,但是没有ts的全路径,需要用抓包工具去抓取上面m3u8视频地址的网站点击播放,抓取ts的地址拼接方式,我这边抓到的是https://rescdn.yishihui.com/longvideo/videocomposite/output/live/696380/1583998162597time-1LD-00001.ts,所以得到ts拼接的前缀是:https://rescdn.yishihui.com/longvideo/videocomposite/output/live/696380/
下一步是通过字符串处理上面的m3u8文件,得到所有的ts文件名:1583998162597time-1LD-00001.ts、1583998162597time-1LD-00002.ts、1583998162597time-1LD-00003.ts、1583998162597time-1LD-00004.ts....然后按顺序依次ts的内容,追加的方式存放到一个文件tmp_out.ts,然后利用插件(ffmpeg)转换tmp_out.ts为mp4格式,如果直接保存为tmp_out.mp4的话,视频播放软件是可以播放的,但是网页的形式是不能播放的,因为字符编码缺少了视频信息,所以需要插件来转换格式。
准备:安装ffmpeg插件
windows安装ffmpeg:
下载地址:https://ffmpeg.org/download.html
下载解压,命令行进入到加压文件夹/bin/目录下就可以直接使用ffmpeg命令
linux安装ffmpeg:
下载地址:https://ffmpeg.org/download.html
下载完上传到linux服务器,解压xz:
xz -d ffmpeg-git-amd64-static.tar.xz
解压tar:
tar -xvf ffmpeg-git-amd64-static.tar
进入解压目录,编译安装:
cd ffmpeg
./ffmpeg
安装完成
PHP完整的实现代码:
$value) {
if($key == 0) continue;
$value = trim($value);
$ts_file[] = substr($value, 0, strpos($value, '.ts') + 3);
}
$url_prefix = substr($url, 0, strpos($url, '.m3u8'));
$url_prefix = substr($url, 0, strrpos($url, '/') + 1);
$file_content = '';
foreach ($ts_file as $key => $value) {
$file_content .= file_get_contents($url_prefix . $value);
}
file_put_contents('tmp_out.ts', $file_content);
// FFMPEG_PATH 是你自己解压ffmpeg的bin路径,例如我的是F:/ffmpeg/bin/
exec(FFMPEG_PATH . "ffmpeg -i tmp_out.ts tmp_out.mp4");