網站視頻播放慢的解決方案

近期做了一個視頻培訓項目,使用了文件服務器存放視頻文件。但是播放效果不理想,部分手機端用戶(主要是移動的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字樣
[java@iZt4n36uo36nxgg8z2hb2kZ 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;
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章