操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    盡管目前人們的娛樂方式越來越多,但是電影永遠是娛樂生活最重要的組成部分之一,這也是多年以來視頻播放器永遠是電腦里必不可少的軟件之一。

    盡管目前在線視頻已經越來越成為市面上的主流,但是快進時惱人的加載和時不時就出現的和諧「圣光」實在是煩。

    除了「圣光」,還有「暗牧」

    一款優秀的視頻播放器會讓你的觀影之旅更加舒適,今天我們就給大家推薦 4 個平臺的 5 款播放器。

    什么樣的播放器是一枚好播放器?

    我相信絕大多數用戶都用過視頻播放器,但是可能并沒有想過一款優秀的播放器有哪些要求。

    在我們看來,一款優秀的播放器基本來說有這些需求:

    ·支持足夠多的格式

    除了市面上主流的 MP4、AVI、MKV、FLV 等等的主流格式之外,VOB、WMV、WEBM、XviD 等等的非主流視頻格式也要能夠支持。

    ·播放大文件時性能強勁,播放小文件時快速輕便

    在播放畫質優秀、聲效震撼但是文件巨大的視頻文件時能夠充分調用系統硬件和軟件方面的性能能,實現流暢播放;播放輕量級文件時又不會過多占用系統資源,節約系統性能。

    ·字幕文件支持豐富

    不但能夠支持普通的外掛字幕,還能夠支持 ASS 特效字幕。

    ·界面簡單美觀

    系統界面簡潔流暢,不影響觀影體驗;基礎操作位置明顯,方便控制;除了點按之外有其它操作方式,比如桌面平臺的鍵盤快捷鍵,移動平臺的手勢操作。

    ·軟件本身綠色、干凈

    軟件沒有任何的插入或植入式廣告,沒有捆綁軟件,簡單輕量,無冗余文件;最好是開源軟件;最好是無需安裝,解壓即可用。

    基于這些要求,我們為大家挑選出了如下播放器。

    MPV-EASY Player

    也許是最優秀的「純」播放器

    在介紹這款播放器之前,首先要介紹一下這款播放器的「母親」 —— mpv。

    mpv 這款播放器或許是目前最強的播放器了,它支持基本上所有格式的視頻和音頻文件格式、支持 ASS 特效字幕、性能優秀,配置靈活;更重要的是它支持 Windows、OS、Linux 等等眾多平臺,而且支持非常強大的自定義功能,甚至還可以外掛腳本。

    只不過這么強大的播放器使用起來非常復雜,基礎版本甚至連 GUI 界面都沒有,所以入門門檻比較高。

    而這里推薦的 MPV-EASY Player 就是 mpv 的簡化版本,在繼承了 mpv 諸多優點之外,還簡化了 mpv 的使用,讓普通用戶也能體驗 mpv。

    MPV-EASY Player 不需要安裝,解壓即可用。

    MPV-EASY Player 的主界面非常簡單,除了基礎操作之外還可以一鍵切換音軌和字幕,剩下的絕大部分操作與設置都在右上角的下拉菜單之中。

    MPV-EASY Player 支持鍵盤快捷鍵,不過功能稍顯簡單。

    除了播放質量之外,MPV-EASY Player 最大的優點是播放時非常節約資源,尤其是播放大文件時非常節約內存和處理器;而且播放效果非常好,無論是視頻還是音效都非常優秀;無論是快進快退還是拖拽進度條都非常流暢。

    不過這款播放器最大的缺點就是播放列表位置比較深,不適合多個視頻文件來回切換。而且基本除了播放視頻之外沒有別的功能。因此如果你想選擇一款純粹的播放器,MPV-EASY Player 絕對是最佳選擇之一。

    Potplayer

    Windows 上的全能之選

    這款大名鼎鼎的播放器是目前我的主力之選,再沒有特殊情況下我基本都會用 potplayer 播放視頻。

    potplayer 解碼功能非常強大,這種強大不只體現在支持文件格式眾多的基礎上,而且還有對視頻文件強大的解碼能力上,potplayer 是我個人日常體驗中為數不多的加速播放視頻音軌不會「壞掉」的播放器。

    而且 potplayer 除了基礎的播放功能還有很多額外的使用功能,比如逐幀播放、片段錄制等等。

    potplayer 還支持非常完善的鍵盤控制,絕大多數需要點按的功能都能夠通過鍵盤進行操作。

    除此之外 potplayer 還有非常多優秀的皮膚可以更換。

    資源占用方面雖然比不了 MPV-EASY Player,但是也不算大;只是在播放相對較大的文件時快進快退會出現卡頓。

    potplayer 最大的缺點是功能實在太多,學習成本比較高;而且右鍵菜單是在是太復雜了……

    IINA

    Mac 上的「Potplayer」

    如果說 Windows 上最好的播放器是上面兩款,那么 Mac 上最優秀的就只有這一款了。

    IINA,免費且開源,使用 swift 編程語言「制造」,為 OS X 而生。

    IINA 界面本身就遵循著 OS X 的設計語言,整個界面都和 Mac OS 的設計非常合拍。

    這款播放器的內核是前面提到過的 mvp,所以無論是解碼還是播放都沒有什么問題。而且是 Mac 平臺上少數對于外掛字幕支持非常良好的播放器。

    除了本地視頻 IINA 還支持 URL 鏈接輸入,可以在軟件內播放在線視頻。

    IINA 對 Mac 平臺的支持也非常好,除了觸控板之外還支持最新的 touchbar。

    總的來說,這款播放器無論是外觀還是性能都是 Mac 平臺上的佼佼者,非常值得一試。

    nPlayer

    iOS 平臺的王者

    相較于桌面平臺,移動平臺的本地播放器相對比較少,畢竟本地存儲大小直接限制了移動端觀看本地視頻。但是也不是沒有,iOS 平臺上最優秀的當屬這款 nPlayer。

    這款應用有付費和免費兩個版本,免費就是有廣告,剩下的功能都基本一致。

    啟動之后能夠檢索手機本地存儲中的影音文件,同時還可以鏈接 WebDAV、FTP、SFTP、DLNA 等以及 icloud、onedrive 等網盤,非常方便。

    軟件支持的格式非常多;解碼能力也很強大,4K 影片也能流暢播放;甚至還支持 7.1 聲道。

    這款播放器甚至還支持匹配字幕和畫中畫模式,體驗非常好。

    軟件本身可調節的選項也非常多,算得上是 iOS 平臺最強播放器了。

    MX Player

    廉頗未老

    作為安卓平臺最「元老」級的應用,用子章的話說:“Android 2 時代就是它,現在還是它。”沒辦法,就是這么優秀。

    和 nPlayer 的體驗類似,MX Player 也能夠播放手機本地的內容,支持格式非常多;但是不足的是 MX Player 不支持網絡存儲位置的播放,但是支持網絡串流的視頻播放。

    MX Player 支持內嵌字幕和外掛字幕,還可以在線搜索字幕;播放時可以選擇音軌。

    同時 MX Player 的多核心解碼能力非常優秀,也是安卓平臺為數不多支持多核心解碼的播放器。

    如果你在安卓平臺有視頻播放器的需求,MX Player 這個老人家還是最好的選擇之一。

    以上五款播放器就是我們給大家的推薦。如果你有其它選擇,也歡迎在留言區分享給大家。

    撰文 / 愷倫

    編輯 / 愷倫

    責任編輯 / 纖塵

    公眾號視覺 / 又耳

    ? 愛否科技原創內容 轉載請聯系后臺

    「愿意點廣告,請我們喝一瓶礦泉水?」

    視頻點播

    1. 視頻點播需求分析

    1.1 需求描述

    視頻點播需求如下:

    1、學生可以在windows瀏覽器上在線觀看視頻。

    2、播放器具有快進、快退、暫停等基本功能。

    1.2 視頻點播解決方案

    1.2.1 流媒體

    • 流媒體

    詳細參考:https://baike.baidu.com/item/%E6%B5%81%E5%AA%92%E4%BD%93/98740?fr=aladdin

    概括理解:流媒體就是將視頻文件分成許多小塊兒,將這些小塊兒作為數據包通過網絡發送出去,實現一邊傳輸視頻 數據 包一邊觀看視頻。

    • 流式傳輸

    在網絡上傳輸音、視頻信息有兩個方式:下載和流式傳輸。

    下載:就是把音、視頻文件完全下載到本機后開始播放,它的特點是必須等到視頻文件下載完成方可播放,播放等待時間較長,無法去播放還未下載的部分視頻。

    流式傳輸:就是客戶端通過鏈接視頻服務器實時傳輸音、視頻信息,實現“邊下載邊播放”。

    流式傳輸包括如下兩種方式:

    1) 順序流式傳輸

    即順序下載音、視頻文件,可以實現邊下載邊播放,不過,用戶只能觀看已下載的視頻內容,無法快進到未下載的視頻部分,順序流式傳輸可以使用Http服務器來實現,比如Nginx、Apache等。

    2)實時流式傳輸

    實時流式傳輸可以解決順序流式傳輸無法快進的問題,它與Http流式傳輸不同,它必須使用流媒體服務器并且使用流媒體協議來傳輸視頻,它比Http流式傳輸復雜。常見的實時流式傳輸協議有RTSP、RTMP、RSVP等。

    • 流媒體系統的概要結構

    通過流媒體系統的概要結構學習流媒體系統的基本業務流程。

    1、將原始的視頻文件通過編碼器轉換為適合網絡傳輸的流格式,編碼后的視頻直接輸送給媒體服務器。

    原始的視頻文件通常是事先錄制好的視頻,比如通過攝像機、攝像頭等錄像、錄音設備采集到的音視頻文件,體積較大,要想在網絡上傳輸需要經過壓縮處理,即通過編碼器進行編碼 。

    2、媒體服務獲取到編碼好的視頻文件,對外提供流媒體數據傳輸接口,接口協議包括 :HTTP、RTSP、RTMP等

    3、播放器通過流媒體協議與媒體服務器通信,獲取視頻數據,播放視頻。

    1.2.2 點播方案

    本項目包括點播和直播兩種方式,我們先調研點播的方案,如下:

    1、 播放器通過 http協議從http服務器上下載視頻文件進行播放

    問題:必須等到視頻下載完才可以播放,不支持快進到某個時間點進行播放

    2、 播放器通過rtmp協議連接媒體服務器以實時流方式播放視頻

    使用rtmp協議需要架設媒體服務器,造價高,對于直播多采用此方案。

    3、 播放器使用HLS協議連接http服務器(Nginx、Apache等)實現近實時流方式播放視頻

    HLS協議規定:基于Http協議,視頻封裝格式為ts,視頻的編碼格式為H264,音頻編碼格式為MP3、AAC或者AC-3

    • HLS是什么 ?

    HLS的工作方式是:將視頻拆分成若干ts格式的小文件,通過m3u8格式的索引文件對這些ts小文件建立索引。一般10秒一個ts文件,播放器連接m3u8文件播放,當快進時通過m3u8即可找到對應的索引文件,并去下載對應的ts文件,從而實現快進、快退以近實時 的方式播放視頻。

    IOS、Android設備、及各大瀏覽器都支持HLS協議。

    詳細參考:https://baike.baidu.com/item/HLS/8328931?fr=aladdin

    采用HLS方案即可實現邊下載邊播放,可以不用使用rtmp等流媒體協議,不用構建專用的媒體服務器,節省成本。

    本項目點播方案確定為方案3。

    2 FFmpeg 的基本使用

    我們將視頻錄制完成后,使用視頻編碼軟件對視頻進行編碼,本項目 使用FFmpeg對視頻進行編碼 。

    下載 :ffmpeg-20180227-fa0c9d6-win64-static.zip,并解壓,本教程將ffmpeg解壓到了C:\Java_Soft\xczx\ffmpeg-20180227-fa0c9d6-win64-static下。

    FFmpeg被許多開源項目采用,QQ影音、暴風影音、VLC等。

    下載:FFmpeg https://www.ffmpeg.org/download.html#build-windows

    將C:\Java_Soft\xczx\ffmpeg-20180227-fa0c9d6-win64-static\bin目錄配置在path環境變量中。

    簡單的測試:

    將一個.avi文件轉成mp4、mp3、gif等。

    比如我們將lucene.avi文件轉成mp4,運行如下命令:

    ffmpeg -i lucene.avi lucene.mp4

    轉成mp3:ffmpeg -i lucene.avi lucene.mp3

    轉成gif:ffmpeg -i lucene.avi lucene.gif

    官方文檔(英文):http://ffmpeg.org/ffmpeg.html

    2.1 生成m3u8/ts文件

    使用ffmpeg生成 m3u8的步驟如下:

    第一步:先將avi視頻轉成mp4

    ffmpeg.exe -i  lucene.avi -c:v libx264 -s 1280x720 -pix_fmt yuv420p -b:a 63k -b:v 753k -r 18 .\lucene.mp4

    下面把各參數意思大概講講,大概了解意思即可,不再此展開流媒體專業知識的講解。

    -c:v 視頻編碼為x264 ,x264編碼是H264的一種開源編碼格式。

    -s 設置分辨率

    -pix_fmt yuv420p:設置像素采樣方式,主流的采樣方式有三種,YUV4:4:4,YUV4:2:2,YUV4:2:0,它的作用是根據采樣方式來從碼流中還原每個像素點的YUV(亮度信息與色彩信息)值。

    -b 設置碼率,-b:a和-b:v分別表示音頻的碼率和視頻的碼率,-b表示音頻加視頻的總碼率。碼率對一個視頻質量有很大的作用。

    -r:幀率,表示每秒更新圖像畫面的次數,通常大于24肉眼就沒有連貫與停頓的感覺了。

    第二步:將mp4生成m3u8

     ffmpeg -i  lucene.mp4   -hls_time 10 -hls_list_size 0  -hls_segment_filename ./hls/lucene_%05d.ts ./hls/lucene.m3u8

    -hls_time 設置每片的長度,單位為秒

    -hls_list_size n: 保存的分片的數量,設置為0表示保存所有分片

    -hls_segment_filename :段文件的名稱,%05d表示5位數字

    生成的效果是:將lucene.mp4視頻文件每10秒生成一個ts文件,最后生成一個m3u8文件,m3u8文件是ts的索引文件。

    使用VLC打開m3u8文件,測試播放效果,VLC 是一款自由、開源的跨平臺多媒體播放器及框架,可播放大多數多媒體文件,以及 DVD、音頻 CD、VCD 及各類流媒體協議。(http://www.videolan.org/)

    3. 視頻(媒資)處理

    開發環境

    1. 創建媒資數據庫

    導入shcool.sql

    2. 創建媒資服務工程

    基于springboot創建工程

    3. 上傳文件

    3.1 斷點續傳解決方案

    通常視頻文件都比較大,所以對于媒資系統上傳文件的需求要滿足大文件的上傳要求。http協議本身對上傳文件大小沒有限制,但是客戶的網絡環境質量、電腦硬件環境等參差不齊,如果一個大文件快上傳完了網斷了,電斷了沒有上傳完成,需要客戶重新上傳,這是致命的,所以對于大文件上傳的要求最基本的是斷點續傳。

    什么是斷點續傳:

    引用百度百科:斷點續傳指的是在下載或上傳時,將下載或上傳任務(一個文件或一個壓縮包)人為的劃分為幾個部分,每一個部分采用一個線程進行上傳或下載,如果碰到網絡故障,可以從已經上傳或下載的部分開始繼續上傳下載未完成的部分,而沒有必要從頭開始上傳下載,斷點續傳可以提高節省操作時間,提高用戶體驗性。

    上傳流程如下:

    1、上傳前先把文件分成塊

    2、一塊一塊的上傳,上傳中斷后重新上傳,已上傳的分塊則不用再上傳

    3、各分塊上傳完成最后合并文件


    文件下載則同理。

    3.2 文件分塊與合并

    為了更好的理解文件分塊上傳的原理,下邊用java代碼測試文件的分塊與合并。

    3.3 文件分塊

    文件分塊的流程如下:

    1、獲取源文件長度

    2、根據設定的分塊文件的大小計算出塊數

    3、從源文件讀數據依次向每一個塊文件寫數據

    //測試文件分塊方法
        @Test
        public void testChunk() throws IOException {
            File sourceFile = new File("F:/develop/ffmpeg/lucene.mp4");
    //        File sourceFile = new File("d:/logo.png");
            String chunkPath = "F:/develop/ffmpeg/chunk/";
            File chunkFolder = new File(chunkPath);
            if(!chunkFolder.exists()){
                chunkFolder.mkdirs();
            }
            //分塊大小
            long chunkSize = 1024*1024*1;
            //分塊數量
            long chunkNum = (long) Math.ceil(sourceFile.length() * 1.0 / chunkSize );
            if(chunkNum<=0){
                chunkNum = 1;
            }
            //緩沖區大小
            byte[] b = new byte[1024];
            //使用RandomAccessFile訪問文件
            RandomAccessFile raf_read = new RandomAccessFile(sourceFile, "r");
            //分塊
            for(int i=0;i<chunkNum;i++){
                //創建分塊文件
                File file = new File(chunkPath+i);
                boolean newFile = file.createNewFile();
                if(newFile){
                    //向分塊文件中寫數據
                    RandomAccessFile raf_write = new RandomAccessFile(file, "rw");
                    int len = -1;
                    while((len = raf_read.read(b))!=-1){
                        raf_write.write(b,0,len);
                        if(file.length()>chunkSize){
                            break;
                        }
                    }
                    raf_write.close();
                }
    
            }
            raf_read.close();
    ?
        }

    3.4 文件合并

    文件合并流程:

    1、找到要合并的文件并按文件合并的先后進行排序

    2、創建合并文件

    3、依次從合并的文件中讀取數據向合并文件寫入數據

    //測試文件合并方法
    @Test
    public void testMerge() throws IOException {
        //塊文件目錄
        File chunkFolder = new File("F:/develop/ffmpeg/chunk/");
        //合并文件
        File mergeFile = new File("F:/develop/ffmpeg/lucene1.mp4");
        if(mergeFile.exists()){
            mergeFile.delete();
        }
        //創建新的合并文件
        mergeFile.createNewFile();
        //用于寫文件
        RandomAccessFile raf_write = new RandomAccessFile(mergeFile, "rw");
        //指針指向文件頂端
        raf_write.seek(0);
        //緩沖區
        byte[] b = new byte[1024];
        //分塊列表
        File[] fileArray = chunkFolder.listFiles();
        // 轉成集合,便于排序
        List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));
        // 從小到大排序
        Collections.sort(fileList, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                if (Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())) {
                    return -1;
                }
                return 1;
            }
        });
        //合并文件
        for(File chunkFile:fileList){
            RandomAccessFile raf_read = new RandomAccessFile(chunkFile,"rw");
            int len = -1;
            while((len=raf_read.read(b))!=-1){
                raf_write.write(b,0,len);
    ?
            }
            raf_read.close();
        }
        raf_write.close();
    ?
    }

    4. 前端頁面

    WebUploader介紹

    如何在web頁面實現斷點續傳?

    常見的方案有:

    1、通過Flash上傳,比如SWFupload、Uploadify。

    2、安裝瀏覽器插件,變相的pc客戶端,用的比較少。

    3、Html5

    隨著html5的流行,本項目采用Html5完成文件分塊上傳。

    本項目使用WebUploader完成大文件上傳功能的開發,WebUploader官網地址:http://fexteam.gz01.bdysite.com/webuploader/

    使用WebUploader上傳流程如下:

    鉤子方法

    在webuploader中提供很多鉤子方法,下邊列出一些重要的:

    本項目使用如下鉤子方法:

    1)before-send-file

    在開始對文件分塊兒之前調用,可以做一些上傳文件前的準備工作,比如檢查文件目錄是否創建完成等。

    2)before-send

    在上傳文件分塊之前調用此方法,可以請求服務端檢查分塊是否存在,如果已存在則此分塊兒不再上傳。

    3)after-send-file

    在所有分塊上傳完成后觸發,可以請求服務端合并分塊文件。

    注冊鉤子方法源代碼:

     
    WebUploader.Uploader.register({
        "before-send-file":"beforeSendFile",
        "before-send":"beforeSend",
        "after-send-file":"afterSendFile"
      }

    構建WebUploader

    使用webUploader前需要創建webUploader對象。

    指定上傳分塊的地址:/api/media/upload/uploadchunk

     
    // 創建uploader對象,配置參數
    this.uploader = WebUploader.create(
      {
        swf:"/static/plugins/webuploader/dist/Uploader.swf",//上傳文件的flash文件,瀏覽器不支持h5時啟動flash
        server:"/api/media/upload/uploadchunk",//上傳分塊的服務端地址,注意跨域問題
        fileVal:"file",//文件上傳域的name
        pick:"#picker",//指定選擇文件的按鈕容器
        auto:false,//手動觸發上傳
        disableGlobalDnd:true,//禁掉整個頁面的拖拽功能
        chunked:true,// 是否分塊上傳
        chunkSize:1*1024*1024, // 分塊大小(默認5M)
        threads:3, // 開啟多個線程(默認3個)
        prepareNextFile:true// 允許在文件傳輸時提前把下一個文件準備好
      }
    )

    before-send-file

    文件開始上傳前前端請求服務端準備上傳工作。

    type:"POST",
    url:"/api/media/upload/register",
    data:{
      // 文件唯一表示
      fileMd5:this.fileMd5,
      fileName: file.name,
      fileSize:file.size,
      mimetype:file.type,
      fileExt:file.ext
    }

    before-send

    上傳分塊前前端請求服務端校驗分塊是否存在。

     
    type:"POST",
    url:"/api/media/upload/checkchunk",
    data:{
      // 文件唯一表示
      fileMd5:this.fileMd5,
      // 當前分塊下標
      chunk:block.chunk,
      // 當前分塊大小
      chunkSize:block.end-block.start
    }

    after-send-file

    在所有分塊上傳完成后觸發,可以請求服務端合并分塊文件。

     
    type:"POST",
    url:"/api/media/upload/mergechunks",
    data:{
      fileMd5:this.fileMd5,
      fileName: file.name,
      fileSize:file.size,
      mimetype:file.type,
      fileExt:file.ext
    }

    頁面效果

    學員使用:

    1. 直接解壓資料xc-ui-pc-teach到webstorm工作目錄
    2. 通過nginx訪問,在nginx中配置 (解決跨域)
    server {
            listen       82;     
            server_name localhost;     
            
            #視頻中心     
            location / {        
                proxy_pass http://127.0.0.1:12000; 
                proxy_set_header Host $http_host;     
                add_header Access-Control-Allow-Origin *;         
                add_header Access-Control-Allow-Credentials true;           
                add_header Access-Control-Allow-Methods GET;            
            } 
    ?
            #媒資管理后臺跨域     
            location ^~ /api/media/ {       
                proxy_pass http://127.0.0.1:9000/media/; 
    ?
                proxy_set_header Host $http_host;  
                add_header Access-Control-Allow-Origin *;         
                add_header Access-Control-Allow-Credentials true;           
                add_header Access-Control-Allow-Methods "GET,POST,OPTIONS";         
            }                
        }

    可以訪問 http://127.0.0.1:12000/#/media/upload 或者 http://localhost:82/#/media/upload/ 查看頁面效果。

    5. 媒資服務端編寫

    服務端需要實現如下功能:

    1、上傳前檢查上傳環境

    檢查文件是否上傳,已上傳則直接返回。

    檢查文件上傳路徑是否存在,不存在則創建。

    2、分塊檢查

    檢查分塊文件是否上傳,已上傳則返回true。

    未上傳則檢查上傳路徑是否存在,不存在則創建。

    3、分塊上傳

    將分塊文件上傳到指定的路徑。

    4、合并分塊

    將所有分塊文件合并為一個文件。

    在數據庫記錄文件信息。



    • 由于上傳過程復雜,開發時按業務流程分別實現。
    1. 配置

    application.yml配置上傳文件的路徑:

    xc-service-manage-media:
      upload-location: C:/school/video/  # 媒資保存路徑
      ffmpeg-path: C:/Java_Soft/xczx/ffmpeg-20180227-fa0c9d6-win64-static/bin/ffmpeg.exe # ffmpeg路徑
    1. 定義Dao

    使用mybatis-plus

    @Mapper
    @Component
    public interface FileMsgMapper extends BaseMapper<FileMsg> {
    }
    1. 定義controller
    @RestController
    @RequestMapping("/media/upload")
    public class MediaUploadController {
    ?
    ?
        @Autowired
        MediaUploadService mediaUploadService;
    ?
        /**
         * 文件上傳前的注冊
         */
    ?
        @PostMapping("/register")
        public ResponseResult register(String fileMd5, String fileName, Long fileSize, String mimetype, String fileExt) {
    ?
            return mediaUploadService.register(fileMd5, fileName, fileSize, mimetype, fileExt);
    ?
        }
    ?
        /**
         * 檢測分塊
         *
         * @param fileMd5
         * @param chunk
         * @param chunkSize
         * @return
         */
    ?
        @PostMapping("/checkchunk")
        public ResponseResult checkchunk(String fileMd5, Integer chunk, Integer chunkSize) {
            return mediaUploadService.checkchunk(fileMd5, chunk, chunkSize);
        }
    ?
        /**
         * 上傳分塊
         *
         * @param file
         * @param fileMd5
         * @param chunk
         * @return
         */
        @PostMapping("/uploadchunk")
        public ResponseResult uploadchunk(MultipartFile file, String fileMd5, Integer chunk) {
            return mediaUploadService.uploadchunk(file, fileMd5, chunk);
        }
    ?
        /**
         * 合并分塊
         *
         * @param fileMd5
         * @param fileName
         * @param fileSize
         * @param mimetype
         * @param fileExt
         * @return
         */
        @PostMapping("/mergechunks")
        public ResponseResult mergechunks(String fileMd5, String fileName, Long fileSize, String mimetype, String fileExt) {
            return mediaUploadService.mergechunks(fileMd5, fileName, fileSize, mimetype, fileExt);
        }
    }
    ?
    1. 定義service (略)由于代碼過多,請參見源碼。

    現在視頻已經通過斷點續傳的方式,上傳到了我們的媒資服務器, 接下來就要使用FFmpeg將視頻轉換成 流媒體。

    6.視頻處理技術方案

    如何通過程序進行視頻處理?

    ffmpeg是一個可行的視頻處理程序,可以通過Java調用ffmpeg.exe完成視頻處理。

    在java中可以使用Runtime類和Process Builder類兩種方式來執行外部程序,工作中至少掌握一種。

    本項目使用Process Builder的方式來調用ffmpeg完成視頻處理。

    關于Process Builder的測試如下 :

     @Test
        public void testProcessBuilder(){
            ProcessBuilder processBuilder = new ProcessBuilder();
    //       processBuilder.command("ping","127.0.0.1");
           processBuilder.command("ipconfig");
            //將標準輸入流和錯誤輸入流合并,通過標準輸入流讀取信息
            processBuilder.redirectErrorStream(true);
            try {
                //啟動進程
                Process start = processBuilder.start();
                //獲取輸入流
                InputStream inputStream = start.getInputStream();
                //轉成字符輸入流
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"gbk");
                int len = -1;
                char[] c = new char[1024];
                StringBuffer outputString = new StringBuffer();
                //讀取進程輸入流中的內容
                while ((len= inputStreamReader.read(c))!=-1) {
                    String s = new String(c,0,len);
                    outputString.append(s);
                    System.out.print(s);
                }
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Test
        public void testFFmpeg(){
            ProcessBuilder processBuilder = new ProcessBuilder();
            //定義命令內容
            List<String> command = new ArrayList<>();
            command.add("D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe");
            command.add("-i");
            command.add("E:\\ffmpeg_test\\1.avi");
            command.add("-y");//覆蓋輸出文件
            command.add("-c:v");
            command.add("libx264");
            command.add("-s");
            command.add("1280x720");
            command.add("-pix_fmt");
            command.add("yuv420p");
            command.add("-b:a");
            command.add("63k");
            command.add("-b:v");
            command.add("753k");
            command.add("-r");
            command.add("18");
            command.add("E:\\ffmpeg_test\\1.mp4");
            processBuilder.command(command);
            //將標準輸入流和錯誤輸入流合并,通過標準輸入流讀取信息
            processBuilder.redirectErrorStream(true);
            try {
                //啟動進程
                Process start = processBuilder.start();
                //獲取輸入流
                InputStream inputStream = start.getInputStream();
                //轉成字符輸入流
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"gbk");
                int len = -1;
                char[] c = new char[1024];
                StringBuffer outputString = new StringBuffer();
                //讀取進程輸入流中的內容
                while ((len= inputStreamReader.read(c))!=-1) {
                    String s = new String(c,0,len);
                    outputString.append(s);
                    System.out.print(s);
                }
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    我們已經準備好了工具類:

    Mp4VideoUtil.java完成avi轉mp4

    HlsVideoUtil.java完成mp4轉hls

    可以直接使用。

    6.1 處理流程

    當視頻合并成功后

    1. 把視頻處理成m3u8流媒體
    2. 把視頻信息寫到數據庫

    具體代碼: 在合并完成方法中調用

        @Value("${xc-service-manage-media.ffmpeg-path}")
        String ffmpeg_path;
    ?
    ?
        private void ChangeHLS(File mergeFile, String fileMd5) {
    ?
            // mp4 文件保存目錄
            String fileFolderPath = getFileFolderPath(fileMd5);
            //生成的mp4的文件名稱
            String mp4_name = fileMd5 + ".mp4";
            //生成的mp4所在的路徑
            String mp4folder_path = fileFolderPath;
    ?
    ?
            //創建工具類對象
            Mp4VideoUtil mp4VideoUtil = new Mp4VideoUtil(ffmpeg_path, mergeFile.getAbsolutePath(), mp4_name, mp4folder_path);
    ?
            //進行處理
            String result = mp4VideoUtil.generateMp4();
    ?
    ?
            //4、將mp4生成m3u8和ts文件
            //String ffmpeg_path, String video_path, String m3u8_name,String m3u8folder_path
            //mp4視頻文件路徑
            String mp4_video_path = mp4folder_path + mp4_name;
    ?
            //m3u8_name文件名稱
            String m3u8_name = fileMd5 + ".m3u8";
            //m3u8文件所在目錄
            String m3u8folder_path = fileFolderPath + "hls/";
    ?
            HlsVideoUtil hlsVideoUtil = new HlsVideoUtil(ffmpeg_path, mp4_video_path, m3u8_name, m3u8folder_path);
    ?
            //生成m3u8和ts文件
            String tsResult = hlsVideoUtil.generateM3u8();
    ?
            //保存fileUrl(此url就是視頻播放的相對路徑)
            String filePath = fileFolderPath + "hls/" + m3u8_name;
    ?
    ?
            // 將fileUrl 保存到數據庫
            FileMsg fileMsg = new FileMsg();
            fileMsg.setFileId(fileMd5);
            fileMsg.setFileName(mergeFile.getName());
            fileMsg.setFilePath(filePath);
            fileMsg.setFileUrl(filePath.split("C:/school/video")[1]);
    ?
            fileMsgMapper.insert(fileMsg);
    ?
    ?
            //優化:  文件處理成功后, 可以刪除mp4文件
    ?
    ?
        }

    說明:

    mp4轉成m3u8如何判斷轉換成功?

    第一、根據視頻時長來判斷,同mp4轉換成功的判斷方法。

    第二、最后還要判斷m3u8文件內容是否完整。

    4 播放器

    4.1 技術選型

    視頻編碼后要使用播放器對其進行解碼、播放視頻內容。在web應用中常用的播放器有flash播放器、H5播放器或瀏覽器插件播放器,其中以flash和H5播放器最常見。

    flash播放器:缺點是需要在客戶機安裝Adobe Flash Player播放器,優點是flash播放器已經很成熟了,并且瀏覽器對flash支持也很好。

    H5播放器:基于h5自帶video標簽進行構建,優點是大部分瀏覽器支持H5,不用再安裝第三方的flash播放器,并且隨著前端技術的發展,h5技術會越來越成熟。

    本項目采用H5播放器,使用Video.js開源播放器。

    Video.js是一款基于HTML5世界的網絡視頻播放器。它支持HTML5和Flash視頻,它支持在臺式機和移動設備上播放視頻。這個項目于2010年中開始,目前已在40萬網站使用。

    官方地址:http://videojs.com/

    4.2 下載video.js

    Video.js: https://github.com/videojs/video.js

    videojs-contrib-hls: https://github.com/videojs/videojs-contrib-hls#installation

    (videojs-contrib-hls是播放hls的一個插件)

    使用文檔:http://docs.videojs.com/tutorial-videojs_.html

    本教程使用 video.js 6.7.3 版本,videojs-contrib-hls 5.14.1版本

    將資料中提供的plugins賦值到xc-ui-pc-video項目目錄下

    4.3 搭建媒體服務器

    正常使用video.js播放視頻是通過一個網頁,用戶通過瀏覽器打開網頁去播放視頻,網頁和視頻都從web服務器請求。

    4.3.1 Nginx媒體服務器

    根據上邊的流程,我們在媒體服務器上安裝Nginx,并配置如下 :

    server {    
            listen       81;
            server_name  localhost;
            
            #  流媒體 靜態資源
            location ^~ /school/video/ {       
                alias   C:/school/video/;
            }       
            # 視頻靜態資源
            location / {        
                alias   C:/CODE/JAVA/school/xc-ui-pc-video/;
                index  index.html index.htm;
            }       
        }

    4.4 測試video.js

    1. 把資料中的video.html 復制到 C:/CODE/JAVA/school/xc-ui-pc-video/ 如圖:

    上面已經使用nginx 代理 C:/CODE/JAVA/school/xc-ui-pc-video/ 目錄。 所以可以通過http請求直接訪問video.html頁面

    1. 把src路徑修改為自己的媒資訪問路徑
    • 測試:

    用戶打開瀏覽器輸入 http://localhost:81/video.html 。即可打開視頻播放頁面,并播放。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有