欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网站视频播放慢的解决方案

程序员文章站 2023-12-30 19:33:10
...

近期做了一个视频培训项目,使用了文件服务器存放视频文件。但是播放效果不理想,部分手机端用户(主要是移动的4G网络下)播放非常不流畅,

经过一轮探讨和咨询,解决方案如下:

1. 咨询服务器租赁房,得知服务器默认申请的电信的IP网段,因此又申请了移动的ip网段,这样可根据用户的运营商给其分配对应的访问ip。(如果有域名可使用DNS判断匹配,否则只能通过ip手动匹配)

2. 视频做了流化处理。原视频是mp4文件,使用的是开源的ffmpeg

步骤1: 安装ffmpeg工具

不管时windows还是linux安装都很简单。但是在linux安装需要注意的是需要一个插件。需要指定libx264
这里贴出我重新安装的步骤:(参考

#yum安装必要包
yum install autoconf automake cmake freetype-devel gcc gcc-c++ git libtool make mercurial nasm pkgconfig zlib-devel
#安装x264
git clone --depth 1 git://git.videolan.org/x264
ls
cd x264
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" ./configure --enable-static
报错,需要安装nasm 至少2.14,不能用yum install nasm,yum安装是last版本
wget http://www.nasm.us/pub/nasm/releasebuilds/2.14/nasm-2.14.tar.xz
ls
tar Jxvf nasm-2.14.tar.xz 
ls
cd nasm-2.14
ls
./configure 
make && make install
cd ../x264
ls
# 指定PKG_CONFIG_PATH,不指定则在安装ffmpeg就算加--enable-libx264,也会提示找不到。不加,则在转换时提示unknow encoder libx264
PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" ./configure --enable-static
make && make install
cd ..
# 检查是否安装成功
ffmpeg -version
# 安装时默认时加入环境变量,所以在任何地方执行就可以。提示如下,重点是有libx264字样
[[email protected] ffmpeg]$ ffmpeg -version
ffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-28)
configuration: --enable-gpl --enable-nonfree --enable-libfreetype --enable-libx264
libavutil      56. 22.100 / 56. 22.100
libavcodec     58. 35.100 / 58. 35.100
libavformat    58. 20.100 / 58. 20.100
libavdevice    58.  5.100 / 58.  5.100
libavfilter     7. 40.101 /  7. 40.101
libswscale      5.  3.100 /  5.  3.100
libswresample   3.  3.100 /  3.  3.100
libpostproc    55.  3.100 / 55.  3.100

 

ps:实际安装时忘记安装x264,安装后记得要把x264的lib刷到缓存里,否则会找不到

1、首先打开/etc/ld.so.conf文件

2、加入动态库文件所在的目录:执行vi /etc/ld.so.conf,在"include ld.so.conf.d/*.conf"下方增加"/usr/local/lib"。

3、保存后,在命令行终端执行:/sbin/ldconfig -v;其作用是将文件/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache以供使用,因此当安装完一些库文件,或者修改/etc/ld.so.conf增加了库的新搜索路径,需要运行一下ldconfig,使所有的库文件都被缓存到文件/etc/ld.so.cache中,如果没做,可能会找不到刚安装的库。

经过以上三个步骤,"error while loading shared libraries"的问题通常情况下就可以解决了。

 

 

步骤2: 测试,安装成功后,执行转换命令:

令:

ffmpeg -i video2.mp4 -c:v libx264 -hls_time 60 -hls_list_size 0 -c:a aac -strict -2 -f hls t/video2.m3u8

步骤3.以下就是正在转换

 ...略...
com.skyjilygao.util.VideoThread          : frame=    3 fps=0.0 q=0.0 size=N/A time=00:00:01.08 bitrate=N/A speed=2.09x    
com.skyjilygao.util.VideoThread          : frame=   20 fps= 19 q=0.0 size=N/A time=00:00:01.36 bitrate=N/A speed=1.32x    
com.skyjilygao.util.VideoThread          : frame=   29 fps= 17 q=0.0 size=N/A time=00:00:01.49 bitrate=N/A speed=0.85x    
com.skyjilygao.util.VideoThread          : frame=   38 fps= 15 q=0.0 size=N/A time=00:00:01.64 bitrate=N/A speed=0.667x    
com.skyjilygao.util.VideoThread          : frame=   40 fps= 13 q=0.0 size=N/A time=00:00:01.70 bitrate=N/A speed=0.54x    
com.skyjilygao.util.VideoThread          : frame=   48 fps= 13 q=0.0 size=N/A time=00:00:01.83 bitrate=N/A speed=0.485x    
...略...

步骤4 内嵌到代码里(java)

/**
  * 拼接ffmpeg命令:ffmpeg -i test.mp4 -c:v libx264 -hls_time 60 -hls_list_size 0 -c:a aac -strict -2 -f hls output.m3u8
  * @param source
  * @return
  */
    private boolean processM3U8(String source, String target) {
        File targetFile = new File(target);
        File parentDir  = targetFile.getParentFile();
        if (!parentDir.exists()) {
            parentDir.mkdirs();
        }
        List<String> commend = new ArrayList<String>();
        commend.add(ffmpeg);
        commend.add("-i");
        commend.add(source);
        commend.add("-c:v");
        commend.add("libx264");
        commend.add("-hls_time");
        commend.add("60");
        commend.add("-hls_list_size");
        commend.add("0");
        commend.add("-c:a");
        commend.add("aac");
        commend.add("-strict");
        commend.add("-2");
        commend.add("-f");
        commend.add("hls");
        commend.add(target);
        this.cmdList = commend;
        // 通过ProcessBuilder创建
        // processBuilder(commend);
 
        // 通过runtime创建
        runtimeBuilder(getCommand());
        return true;
    }

注意:命令通过list传入,所以遇到空格,下一个参数就是一个list的元素。不能写成 commend.add("-hls_time 60");这样执行会变成ffmpeg -i test.mp4 -c:v libx264 "-hls_time 60" -hls_list_size 0 -c:a aac -strict -2 -f hls output.m3u8导致执行失败
这里是关键代码。

命令简单解释下:
-hls_time 60: 设置每片的长度,我这里是60秒,为一个片段。
-hls_list_size 0:设置播放列表保存的最多条目,我这里设置为0会保存有所片信息,默认值为5
更多命令可以百度或Google


步骤4.在内嵌到代码里(java)

/**
  * 拼接ffmpeg命令:ffmpeg -i test.mp4 -c:v libx264 -hls_time 60 -hls_list_size 0 -c:a aac -strict -2 -f hls output.m3u8
  * @param source
  * @return
  */
    private boolean processM3U8(String source, String target) {
        File targetFile = new File(target);
        File parentDir  = targetFile.getParentFile();
        if (!parentDir.exists()) {
            parentDir.mkdirs();
        }
        List<String> commend = new ArrayList<String>();
        commend.add(ffmpeg);
        commend.add("-i");
        commend.add(source);
        commend.add("-c:v");
        commend.add("libx264");
        commend.add("-hls_time");
        commend.add("60");
        commend.add("-hls_list_size");
        commend.add("0");
        commend.add("-c:a");
        commend.add("aac");
        commend.add("-strict");
        commend.add("-2");
        commend.add("-f");
        commend.add("hls");
        commend.add(target);
        this.cmdList = commend;
        // 通过ProcessBuilder创建
        // processBuilder(commend);
 
        // 通过runtime创建
        runtimeBuilder(getCommand());
        return true;
    }

上一篇:

下一篇: