解决!上传 mp4 到服务器之后,个别视频无法在浏览器播放

使用ffmpeg对视频进行转码,转存后上传七牛云空间,作为视频资源,可在浏览器正常播放

记录一下工作中遇到的问题以及解决方法。

公司站点有些用户需要上传视频资源,文件不大,大多是MP4格式的,但是偶然发现个别视频文件上传之后并不能播放,文件后缀也都是mp4。

查阅相关资料之后,了解到视频的编码格式有多种,但是浏览器一般能识别到的是h264编码的。

最初给产品的建议是在上传入口贴个链接,让用户自行下载转码工具进行转码,但是产品大佬表示多数用户不一定会使用,另外就是用户体验不好。
转而去查阅七牛云的文档,发现七牛提供的有转码服务,迅速莽了一套出来,交给前端调试,最后也通过了。
然鹅,七牛云是要收费!!!
4分钟的视频转码需要3毛钱!
0.03元/4分钟 还是普通清晰度的!
这么大的开支、这么小的公司,领导当然不会批这个钱。

最终查到了ffmpeg这么个东西,看起来能用。

安装 ffmpeg

1 yum install yasm
2 下载x264,www.videolan.org/developers/x264.ht... 在该页面找到对应的资源链接 直接wget下载到服务器.
3 下载ffmpeg ffmpeg.org/download.html 在该页面找到对应的资源链接,直接wget下载到服务器.
4 tar -xjf x264-master.tar.bz2 注意重命名x264在 usr/local/下的名称 和下面的配置相对应 并进入x264目录
5

./configure --prefix=/usr/local/x264 --enable-shared --enable-static --disable-asm
此处prefix对应的路径就是第四步 x264-master.tar.bz2 的解压路径

make
make install
6 返回上一级,tar xjf ffmpeg-4.2.3.tar.bz2
注意重命名ffmpeg文件夹的名称 和配置命令相对应 cd 进入ffmpeg
7

./configure --prefix=/usr/local/ffmpeg --enable-shared --enable-yasm --enable-libx264 --enable-gpl --enable-pthreads --extra-cflags=-I/usr/local/x264/include --extra-ldflags=-L/usr/local/x264/lib 

这里同样要注意x264和ffmpeg的路径问题
make
make install
8 vim /etc/ld.so.conf 在文件末尾加上

/usr/local/ffmpeg/lib/

保存退出 执行 ldconfig
9 vim /etc/profile 文件末添加环境变量:

#set ffmpeg environment
PATH=$PATH:/usr/local/ffmpeg/bin 
export PATH

保存退出 执行 source /etc/profile

10 查看是否成功 ffmpeg -version

注意:
坑:

bash: ffmpeg: command not found

一个简单粗暴的解决办法: 进入/usr/local/ffmpeg/bin 目录
找到 ffmpeg 文件,然后复制到 /usr/local/bin 目录下
然后在给这个目录权限,这一步很重要
sudo chmod -R 777 /usr/local/bin
也可直接创建软连接到usr/local/bin

坑:

ffmpeg: error while loading shared libraries: libx264.so.161: cannot open shared object file: No such file or directory

在 etc/ld.so.conf 下追加

/usr/local/x264/lib/

或者重新编译安装x264

安装完毕,开始调用

$cmd = '/usr/local/ffmpeg/ffmpeg -i  ' . $file_path . ' -c:v libx264 -strict -2 ' . $new_path;
exec($cmd, $log, $status);
\Log::info('视频转码完成', ['new_path' => $new_path, 'log' => $log, 'status' => $status]);

这里需要注意,虽然ffmpeg我们设定了全局变量,在命令行调试的时候是可以成功触发执行的,但是我这里是放到队列里进行调用,发现始终返回127,最后在$cmd这里,带上ffmpeg的绝对路径就可以成功了。
另外,由于视频转码过程比较慢,4分钟的视频,公司的测试服务器转码花了大致10分钟,因此转码过程建议都队列处理,在队列设置里注意设置队里任务的timeout时长

结语

第一次发文,非运维大佬,就是个臭敲代码的,如有纰漏欢迎指正,感谢!

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 3年前 自动加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 8

挺好的,想起我刚工作不久的时候用ffmpeg转过微信语音的格式,折腾了不少时间。另外exec函数建议换成symfony/process组件,这个更安全

3年前 评论
anan6527 (楼主) 3年前

自己转码不是更消耗服务器资源吗 :joy:

3年前 评论
anan6527 (楼主) 3年前
foobar

学习了

3年前 评论
aidoudou 3年前
wanghan

所有领导都一样,只要是免费,就行,他也不管收费的有多牛多好用

3年前 评论
╰ゝSakura

不过这样的做法的话,多了一步很麻烦,你们应该是ToC的吧,如果是ToB的话,直接强制要求只能上传MP4,不管,技术说了算

3年前 评论
anan6527 (楼主) 3年前

像这种视频资源不是应该放到云存储上的吗,放到服务器播放,你们带宽是免费的吗 :joy:

3年前 评论
anan6527 (楼主) 3年前
哓东 3年前
anan6527 (楼主) 3年前

在老板眼里能免费正常使用就行,等用户量起来再讲

3年前 评论
anan6527 (楼主) 3年前

我之前也搞过,后来我那个 1m 的小带宽,看视频的时候实在是慢,还是没有云点播香。另外,转码的过程不需要 php 参与,直接在 linux 里跑也行。

3年前 评论
anan6527 (楼主) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!