最簡單的視頻網站(JavaEE+FFmpeg)

http://blog.csdn.net/leixiaohua1020/article/details/15811977/javascript

 

本文記錄一個最簡單的視頻網站系統。此前作過一些基於JavaEE中的 SSH (Strut2 + Spring + Hibernate)的網站系統,可是一直沒有作過一個視頻網站系統,因此就打算作一個「精簡」的視頻網站系統,以方便之後測試以及學習使用。本視頻網站支持直播(經過RTMP實現)和點播(經過HTTP實現)。爲了保持精簡,這個視頻網站系統僅製做了網絡視頻的管理功能(增刪改查),以及相關的參數配置功能。因爲本身在JavaEE方面沒有深刻學習過,因此這個系統有部分功能還沒搞完,之後有時間再慢慢完善。html

簡介

架構

系統前臺顯示採用了Div + CSS+ Javascript技術。其中前臺顯示用了一些Javascript插件,例如說生成旋轉燈籠式效果的CloudCarousel,生成導航菜單的 ddsmoothmenu,用於表單驗證的jQuery Validation Engine等等。其中視頻播放器用了FlowPlayer(包含了RTMP插件)來支持HTTP的點播和RTMP的直播。按理說視頻文件上傳的時候可使用Ajax實現,可是考慮工做比較繁瑣,因此暫時仍是使用直接文件上傳的方式。java

系統的後臺使用了JavaEE系統中最傳統的三層架構:Action層,Service層以及DAO層。其中Action層使用了Struts2框架,用於處理前臺頁面傳來的請求;DAO層使用了Hibernate框架,用於和數據庫的交互。Spring框架則用於將Action層,Service層以及 DAO層整合起來。系統的先後臺交互主要使用了JSTL標籤和EL表達式。此外考慮到國際化方面的要求,採用了Struts2的i18n方式,將全部頁面上的文字都抽取坐來保存到單獨的文件中,這樣就能夠實現多種語言的顯示。git

系統開始運行後,會開啓兩個線程VideoThumbnailThread和VideoTranscoderThread。 VideoThumbnailThread用於截取視頻的縮略圖,VideoTranscoderThread則用於轉碼上傳的視頻。這兩個線程都是經過調用ffmpeg.exe完成相應的功能。程序員

此外,系統中還包含了查看媒體信息的功能。該功能經過調用MediaInfo.dll完成,再也不詳述。github

整個系統的框架以下圖所示,後文中再詳細記錄每部分的功能。web

效果

系統主要包含了如下幾個頁面:sql

主頁(index.jsp):進入系統的第一個頁面。 
視頻列表(videolist.jsp):列表顯示視頻資源的頁面。按照視頻源的類型的不一樣能夠分爲點播(VOD)視頻列表和直播(Live)視頻列表。 
視頻編輯(videoedit.jsp):編輯視頻資源的頁面。按照視頻源的類型的不一樣能夠分爲點播(VOD)編輯和直播(Live)編輯。按照操做的不一樣能夠分爲添加(Add)和編輯(Edit)。 
視頻內容(videocontent.jsp):查看視頻的內容的頁面。按照視頻源的類型的不一樣能夠分爲點播(VOD)視頻內容和直播(Live)視頻內容。 
設置(configure.jsp):設置頁面。用於配製系統的參數。 
關於(about.jsp):顯示系統相關的一些信息的頁面。
首頁

網站首頁的以下圖所示。Logo位於左上角,菜單欄位於右上角。爲了美觀一些,頁面上方作了一個燈箱效果的特效,隨機顯示一些視頻的縮略圖。頁面下方則分別列出「點播列表」和「直播列表」中最近添加的幾個視頻。數據庫

點播列表

點播列表頁面以下圖所示。在該頁面中,能夠對點播視頻進行簡單的管理:查看內容,添加,修改以及刪除。編程

直播列表

點播列表頁面以下圖所示。直播列表實質上使用了和點播列表相同的頁面。在該頁面中,能夠對直播視頻進行簡單的管理:查看內容,添加,修改以及刪除。

視頻內容頁面

視頻內容頁面以下所示。該頁面中包含了一個FlowPlayer播放器,該播放器用於播放視頻內容。

點播視頻內容頁面以下所示。

直播視頻內容頁面以下所示。儘管表面上看點播和直播頁面徹底類似,可是實際上點播和直播的機制是不同的。點播依靠的是HTTP漸進式下載,而直播依靠的是FlowPlayer的RTMP組件。

視頻添加頁面

點播視頻添加頁面以下所示。該頁面用於上傳一個點播視頻。「名稱」輸入框用於指定視頻的名稱,「文件」用於指定上傳的視頻文件,「簡介」能夠指定針對該視頻的一段簡介。其中,「名稱」和「文件」兩個輸入框爲必填項,不然沒法提交該頁面的表單。

直播視頻添加頁面以下所示。從圖中能夠看出直播和點播的添加頁面很相似。它們的不一樣在於:點播是上傳一個視頻文件,而直播是指定一個URL(目前該URL只支持RTMP)。和點播相似,「名稱」和「URL」兩個輸入框爲必填項,不然沒法提交該頁面的表單。

視頻編輯頁面

點播視頻編輯頁面以下所示。該頁面用於編輯已經完成上傳的點播視頻的信息。

直播視頻編輯頁面以下所示。該頁面用於編輯直播視頻的信息。

配置

系統的配置頁面以下圖所示。該頁面用於配置系統的各類設置(以轉碼設置爲主)。每次配置完成後重啓系統後設置生效。包含如下參數。

  • 視頻編碼器:轉碼使用的視頻編碼器,默認值爲「libx264」。
  • 視頻碼率 (bps) :視頻編碼的碼率(單位爲bps),默認值爲500000(500kbps)。
  • 視頻幀率 (fps) :視頻編碼的幀率(單位爲fps),默認值爲25。
  • 音頻編碼器:轉碼時候使用的音頻編碼器,默認值爲「libmp3lame」。
  • 音頻採樣率 (Hz) :音頻編碼的採樣率(單位爲Hz),默認值爲22050(22.05kHz)。
  • 音頻碼率 (bps) :音頻編碼的碼率(單位爲bps),默認值爲64000(64kbps)。
  • 視頻寬 (pixel) :轉碼後視頻的寬(單位爲pixel),默認值爲640。
  • 視頻高 (pixel) :轉碼後視頻的高(單位爲pixel),默認值爲360。
  • 使用水印:選擇轉碼後的視頻是否加水印。若是該選項選擇「是」,則會在轉碼後的視頻中添加水印。
  • 水印文件路徑:水印文件的路徑,此處爲文件相對於網站根目錄的路徑,默認爲「watermark/svw.png」。
  • 水印位置-x座標 (pixel) :水印在視頻中的位置——x座標(單位爲pixel),默認值爲5。
  • 水印座標-y座標 (pixel) :水印在視頻中的位置——y座標(單位爲pixel),默認值爲5。
  • 保持寬高比而且填充黑邊:選擇轉碼後是否保持寬高比。若是該選項選擇「是」,則轉碼後的視頻會保持寬高比,而且當輸入和輸出視頻寬高比不同的時候,會在輸出視頻中添加黑邊。若是該選項選擇「否」,則轉碼後的視頻會拉伸成輸出分辨率。
  • 輸出視頻封裝格式:輸出視頻的封裝格式,默認爲「flv」。
  • 視頻截圖位置 (sec) :獲取視頻縮略圖的位置(單位爲sec),默認爲5sec。該默認值的含義是獲取視頻第5秒處的視頻幀做爲視頻的縮略圖。
  • 上傳視頻存放文件夾:用於存放上傳的視頻文件,默認值爲「videoori」。
  • 轉碼視頻存放文件夾:用於存放轉碼的視頻文件,默認值爲「video」。
  • 視頻截圖存放文件夾:用於存放視頻的截圖,默認值爲「videothumbnail」。

MediaInfo信息

MediaInfo信息位於視頻內容頁面中,在默認的狀況下是不顯示的。經過修改網頁中代碼能夠顯示視頻的MediaInfo信息。

轉碼前文件信息以下圖所示,從圖中能夠看出轉碼前的文件格式是MPEG-PS,視頻編碼爲MPEG-1,音頻編碼爲MP2。

轉碼後文件信息以下圖所示,從圖中能夠看出轉碼前的文件是FLV格式的,視頻編碼爲H.264,音頻編碼MP3。

多國語言

本系統支持多國語言。選擇右上角菜單的「語言」->「English」能夠將系統切換到英文。英文界面以下圖所示。

英文版的視頻點播列表以下圖所示。

英文版的視頻內容頁面以下圖所示。

英文版的配置界面以下圖所示。

網站部分

下面簡單記錄一下網站部分的關鍵源代碼。分紅三個部分:數據庫、前臺和後臺。

數據庫

系統包含了4張表:video,videostate,category,configure。下面簡單記錄每一個表的含義。

Video表

Video表用於存儲視頻記錄。每個視頻對應Video表中的一條記錄。該表中的字段以下表所示。

image

備註

*其中點播視頻的URL爲視頻文件的相對路徑。

下面例舉Video表中的幾項和URL有關數據(受限於篇幅,省略其它字段)。

image

Videostate表

Videostate表用於存儲視頻的狀態。該表中字段以下表所示。

image

目前按照執行的順序定義了4種狀態:等待上傳,等待截圖,等待轉碼,完成。其中「CSS樣式」用於輔助顯示視頻的狀態。該表的內容以下

image

Category表

Category表用於存儲視頻的分類。該表能夠用於肯定視頻的分類,目前尚未作太多開發。

image

Configure表

Configure表用於存儲系統配置信息。該表中字段以下表所示。

image

該表的內容以下。

image

前臺


前臺部分沒有太多能夠記錄的,基本上都是各類DIV和CSS的調整。其中使用了較多的JSTL標籤以及EL表達式。此外使用了Struts2標籤用於支持國際化。基本的jsp頁面只有6個:

index.jsp:首頁。 
videolist.jsp:視頻列表——直播視頻列表,點播視頻列表。 
videoedit.jsp:視頻編輯——直播視頻添加,直播視頻編輯,點播視頻添加,點播視頻編輯。 
videocontent.jsp:視頻內容——直播視頻內容,點播視頻內容。 
configure.jsp:配置頁面。 
about.jsp:關於頁面。

除了基本頁面以外,還有一些輔助頁面:

cfooter.jsp:頁腳。 
cheader.jsp:標題欄。 
csidebar_recent.jsp:側邊欄(最近添加)。 
error.jsp:錯誤頁面。
FlowPlayer播放器

前臺頁面中用於視頻播放的播放器是FlowPlayer。FlowPlayer播放器安裝有3個步驟: 
(1)包含FlowPlayer的Js文件

<script type="text/javascript" src="videoplayer/flowplayer-3.2.8.min.js"></script>

(2)添加一個<a>標記

<a href="http://www.mywebsite.com/myVideo.flv"  
       style="display:block;width:425px;height:300px;"  
       id="player">  
    </a>

(3)添加一段Javascript代碼,其中要包含FlowPlayer的Swf文件

<script language="JavaScript"> 
  flowplayer("player", "path/to/the/flowplayer-3.2.18.swf");  
</script>

FlowPlayer經過HTTP播放點播視頻文件的源代碼以下所示。${video.url}中保存了視頻的相對URL。

<a id="player" href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/${video.url}"> 
</a> 
<script> 
   flowplayer("player", "videoplayer/flowplayer-3.2.8.swf");  
</script>

FlowPlayer 經過RTMP播放直播視頻文件的示例代碼以下所示。${video.url}中保存了視頻的URL。播放RTMP的時候用到了FlowPlayer的 RTMP Plugin。須要注意的是,RTMP的URL須要拆分開來分別填到不一樣的位置。在這裏經過split(‘/’)函數按照「/」將字符串分離爲字符串數組。而後將「protocol://server/app」填至plugins的netConnectionUrl字段,playpath填至clip的 url字段。

複製代碼
<a id="player"> 
</a> 
<!-- Parse RTMP URL --> 
<script> 
str='${video.url}';  
arr=str.split('/');  
      //rtmp://server/app/playpath  
protocol=arr[0];  
server=arr[2];  
app=arr[3];  
playpath=arr[4];  
lowplayer("player", "videoplayer/flowplayer-3.2.8.swf",{   
        clip: {   
          //scaling:'orig',  
          url: playpath,  
          provider: 'rtmp',  
          live:'true'  
        },    
        plugins: {    
           rtmp: {    
             url: 'videoplayer/flowplayer.rtmp-3.2.8.swf',    
             netConnectionUrl: protocol+'//'+server+'/'+ app  
           }   
       }   
    });  

script>
複製代碼
後臺

後臺部分採用了JavaEE的SSH (Struts2 + Spring + Hibernate)的三層架構,其中的代碼再也不詳細記錄。三層分別爲Action層、Service層和DAO層。其中Action層採用了 Struts2框架,DAO層採用了Hibernate框架,而Spring則整合了這三個層面。

BaseService/BaseDAO

SSH 三層架構雖然在解耦合方面作得很好,可是卻致使開發起來很是繁瑣,嚴重下降了開發的速度。爲了方便起見,本系統中在Service層編寫了 BaseService用於完成通用的Service操做;在DAO層也編寫了BaseDAO用於完成通用的DAO操做。這樣除非有特殊需求,通常狀況下只要調用BaseService中的方法就能夠完成各類基本的操做。BaseService包含的接口以下所示。

複製代碼
/** 
* 最簡單的視頻網站 
* Simplest Video Website 
* 
* 雷霄驊 Lei Xiaohua 
* 
* leixiaohua1020@126.com 
* 中國傳媒大學/數字電視技術 
* Communication University of China / Digital TV Technology 
* http://blog.csdn.net/leixiaohua1020 
* 
* 本程序是一個最簡單的視頻網站視頻。它支持 
* 1.直播 
* 2.點播 
* This software is the simplest video website. 
* It support: 
* 1. live broadcast 
* 2. VOD 
*/ 
package service;  

import java.util.List;  

/** 
* @author 雷霄驊 
* 對Object的Service 
* 包含了一些通用的方法 
*/ 
public interface BaseService {  
/** 
          * 保存一個對象 
          * @param object 一個對象 
          */ 
public void save(Object object);  
/** 
           * 更新一個對象 
           * @param object 一個對象 
           */ 
public void update(Object object);  
/** 
           * 刪除一個對象 
           * @param object 一個對象 
           */ 
public void delete(Object object);  
/** 
           * 根據ID讀取一個指定名稱的對象 
           * @param targetName 對象的名稱 
           * @param id 對象的ID 
           * @return 一個對象 
           */ 
public Object ReadByID(String targetName,int id);  

@SuppressWarnings("rawtypes")  
/** 
           * 獲取指定類型的全部對象 
           * @param targetName 對象類型名稱 
           * @return 對象的列表 
           */ 
public List ReadAll(String targetName);  

@SuppressWarnings("rawtypes")  
/** 
           * 根據「屬性-值」獲取多個指定類型的對象 
           * @param targetName 對象類型名稱 
           * @param propertyName 對象中屬性的名稱 
           * @param propertyValue 對象中屬性的值 
           * @return 對象的列表 
           */ 
public List ReadByProperty(String targetName,String propertyName,Object propertyValue);  

/** 
           * 根據「屬性-值」獲取一個指定類型的對象 
           * @param targetName 對象類型名稱 
           * @param propertyName 對象中屬性的名稱 
           * @param propertyValue 對象中屬性的值 
           * @return 一個對象 
           */ 
public Object ReadSingle(String targetName,String propertyName,Object propertyValue);  

/** 
           * 獲取多個指定類型的對象,能夠限定獲取對象數目的多少,而且根據特定的屬性進行排序。 
           * @param targetName 對象類型名稱 
           * @param propertyName 對象中屬性的名稱,用於排序 
           * @param num 結果對象列表的最大數目 
           * @param order 排序方式,能夠選擇「asc」或者「desc」 
           * @return 對象的列表 
           */ 
public List ReadLimitedByOrder(String targetName,String propertyName,int num,String order);  

/** 
           * 獲取指定類型的對象的數量。 
           * @param targetName 對象類型名稱 
           * @return 數量 
           */ 
public int ReadCount(String targetName);  
/** 
           * 根據「屬性-值」爲條件,獲取指定類型的對象的數量。 
           * @param targetName 對象類型名稱 
           * @param propertyName 對象中屬性的名稱 
           * @param propertyValue 對象中屬性的值 
           * @return 數量 
           */ 
public int ReadCountByProperty(final String targetName,String propertyName, Object value);  
/** 
          * 兩個功能: 
          * 1.根據「屬性-值」獲取多個指定類型的對象 
          * 2.限定獲取對象數目的多少,而且根據特定的屬性進行排序。 
          * @param targetName 對象類型名稱 
          * @param readpropertyName 對象中屬性的名稱,用於獲取對象 
          * @param readvalue 對象中屬性的值 
          * @param orderpropertyName 對象中屬性的名稱,用於排序 
          * @param num 結果對象列表的最大數目 
          * @param order 排序方式,能夠選擇「asc」或者「desc」 
          * @return 
          */ 
public List ReadByPropertyAndLimitedByOrder(final String targetName, final String readpropertyName,  
final Object readvalue,final String orderpropertyName, final int num, final String order);  

}
複製代碼

FFmpeg部分

截取縮略圖線程和轉碼線程

系統在啓動後會開啓兩個線程:VideoThumbnailThread和VideoTranscoderThread。其中 VideoThumbnailThread線程會不停的檢測須要截取縮略圖的視頻,調用相應的FFmpeg命令截取縮略圖;VideoTranscoderThread線程會不停的監測須要轉碼的視頻,調用相應的FFmpeg命令轉碼視頻。何以肯定視頻是否須要截取縮略圖以及是否須要轉碼?這是經過video表中的videostateid字段來標識的。視頻開始上傳後,該視頻記錄會被標記爲「等待上傳」(第1步);上傳完畢後,該視頻記錄會被標記爲「等待截圖」(第2步);截圖完畢後,該視頻記錄會被標記爲「等待轉碼」(第3步);轉碼完畢後,該視頻記錄會被標記爲「完成」(第4步)。VideoThumbnailThread會不停地檢查系統中「等待截圖」的視頻,截圖完成後將視頻標記爲「等待轉碼」;VideoTranscoderThread會不停地檢查系統中「等待轉碼」的視頻,轉碼完成後將視頻標記爲「完成」。

FFmpeg和Java的整合

FFmpeg和Java整合的過程當中有如下幾個須要注意的地方:

(1)路徑的處理

FFmpeg處理視頻的時候須要用到絕對路徑,因此涉及到絕對路徑獲取的問題。使用ServletContext的getRealPath("/")方法能夠得到當前Web應用根目錄的絕對路徑。例如在本身的電腦上下述代碼能夠得到Web應用的據對路徑:

ServletContext servletContext;  
System.out.println(servletContext.getRealPath("/"));

執行完後輸出爲:

D:\MyEclipseWorkspace\.metadata\.me_tcat\webapps\simplest_video_website\

相對路徑中的URL中路徑的分隔採用「/」(正斜槓,Unix系統使用),而上述代碼中路徑的分隔採用「\」(反斜槓,Windows系統使用)。若是把相對文件路徑和絕對目錄路徑拼接起來傳遞給FFmpeg的話,FFmpeg是能夠識別的,可是這樣一來路徑中一會「/」一會「\」會給人一種很彆扭的感受,所以可使用String的replace()方法將「\」統一替換爲「/」,這樣就整齊多了。例以下面代碼:

ServletContext servletContext;  
System.out.println(servletContext.getRealPath("/").replace('\\', '/'));

執行完後輸出爲:

D:/MyEclipseWorkspace/.metadata/.me_tcat/webapps/simplest_video_website/

(2)FFmpeg命令行的調用

FFmpeg命令行的的調用能夠分紅兩個步驟:

(a)生成符合設置的命令

這一步驟實際上就是一個簡單的字符串拼接的過程。根據配置的參數拼接成相應的轉碼命令。須要注意的是,在輸入和輸出的文件路徑兩邊要加上雙引號。不然當文件路徑中包含空格的時候,會致使路徑解析錯誤。

(b)調用命令行

調用命令行使用Runtime.getRuntime().exec(cmdstr)方法就能夠了。其中cmdstr常見的格式有兩種:

cmd /c {FFmpeg Command}  
cmd /c start {FFmpeg Command}

第一種格式是在本窗口中直接執行命令,第二種格式是新打開一個窗口執行命令。第一種方法我在JavaEE環境中測試有問題,並且不彈出窗口不便於調試,因此使用第二種執行方法。

(c)等待調用的命令行執行完畢

Runtime.getRuntime().exec()在調用命令後就直接返回當前線程了。這不符合實際的需求。實際中須要系統完成FFmpeg轉碼工做後,才能作下一步操做。能夠用Process的waitFor()方法阻塞當先線程直至調用程序運行結束。

截取縮略圖命令

FFmpeg截取縮略圖命令以下:

ffmpeg -y -i "ourtime.flv" -ss 5 -s 220x110 -f image2 -vframes 1 "thumbnail.jpg"

參數含義以下:

-y:輸出文件重名的時候,自動覆蓋。 
-i:輸入文件路徑(能夠是相對路徑或者絕對路徑)。 
-ss:截取縮略圖的時間點,這裏是5s處。 
-s:輸出縮略圖的分辨率,這裏是220x110。 
-f:輸出文件格式,這裏的image2表明文件格式爲圖片。 
-vframes:輸出視頻幀的個數,這裏是1。 
最後一個參數爲輸出的縮略圖文件路徑。
轉碼命令

FFmpeg轉碼命令以下:

ffmpeg -y -i "ourtime.flv" -vcodec libx264 -b:v 500000 -r 25 -acodec libmp3lame -b:a 64000 -ar 22050 -vf scale=w=640:h=360:force_original_aspect_ratio=decrease,pad=w=640:h=360:x=(ow-iw)/2:y=(oh-ih)/2[aa];movie=svw.png[bb];[aa][bb]overlay=x=5:y=5 "ourtime_convert.flv"

參數含義以下:

-y:輸出文件重名的時候,自動覆蓋。 
-i:輸入文件路徑(能夠是相對路徑或者絕對路徑)。 
-vcodec:視頻編碼器,這裏是libx264。 
-b:v:視頻碼率,這裏是500000bps。 
-r:視頻幀率,這裏是25fps。 
-acodec:音頻編碼器,這裏是libmp3lame。 
-b:a:音頻碼率,這裏是64000bps。 
-ar:音頻採樣率,這裏是22050Hz。 
-vf:濾鏡,用於圖像拉伸以及水印疊加。 
最後一個參數爲輸出的視頻文件路徑。

Filter(濾鏡)配置

幾句話介紹一下Filter的配置:

  • Filter配置參數使用在FFmpeg的-vf參數以後
  • Filter 之間可使用「,」鏈接,鏈接以後前一個Filter的輸出做爲後一個Filter的輸入。幾個Filter構成一個FilterChain(濾鏡鏈),每一個FilterChain以「;」結尾。幾個Filter Chain能夠構成一個FilterGraph(濾鏡圖)。能夠在Filter的Pad上添加「標籤」用於鏈接其它Filter,Filter標籤的形式爲「[xx]」(其中「xx」能夠隨意寫一些字符,只要能夠起到標記做用就能夠了)。
  • Filter的可使用多個參數,參數之間使用「:」分割。

下面分別記錄幾個濾鏡的使用方法。

【scale濾鏡】

scale濾鏡使用libswscale對圖像進行拉伸。它的參數含義以下:

w:輸出圖像的寬。 
h:輸出圖像的高。
force_original_aspect_ratio:保持視頻寬高比的方法,可使用以下值:(1)disable——不保持寬高比;(2)decrease——須要的時候下降寬或者高;(3)increase——須要的時候提升寬或者高。

有關force_original_aspect_ratio能夠舉個例子:輸入視頻分辨率是1920x800,設置濾鏡爲:

scale=w=640:h=360:force_original_aspect_ratio=decrease

輸出的視頻分辨率爲640x266。 
【pad濾鏡】 
pad濾鏡用於給拉伸後的圖像加「黑邊」。通過scale濾鏡處理以後,視頻的寬必定小於等於640,而視頻的高必定小於等於360,此時須要使用pad濾鏡填充視頻的兩邊(上下或者是左右),保證輸出的視頻的分辨率爲640x360。 
Pad濾鏡有四個基本的參數:

w:填充後視頻的寬度 
h:填充後視頻的高度 
x:輸入視頻的左上角在填充後視頻中的x座標 
y:輸入視頻的左上角在填充後視頻中的y座標

一個基本的如法以下所示:

pad=w=640:h=480:x=0:y=40

上述濾鏡將視頻填充爲640x480,同時將輸入視頻的左上角放在(0,40)的位置上。 
在給視頻加黑邊的過程當中,須要把輸入的視頻放在填充後視頻的中央,而pad濾鏡中輸入視頻的位置是以左上角來肯定的,所以肯定輸入視頻的左上角的座標是一個比較麻煩的事。對此,pad濾鏡提供瞭如下幾個變量。

iw:輸入視頻的寬 
ih:輸入視頻的高 
ow:輸出視頻的寬 
oh:輸出視頻的高

經過上述幾個變量,能夠得知若是想把輸入視頻放在填充後視頻的中央,輸入視頻的x座標應該爲(ow-iw)/2,y座標應該爲(oh-ih)/2。 
【movie濾鏡】 
Movie 濾鏡屬於Source濾鏡,它用於讀取水印圖片文件(通常狀況下是一個PNG文件)。有關movie濾鏡有一個地方須要特別注意:它在Windows下彷佛不支持輸入路徑爲絕對路徑。由於Windows下文件的絕對路徑一般爲「D:\test\......\watermark.png」,即其中開頭的盤符後面跟着一個「:」。「:」在Filter中是一個特殊字符,會被解析成參數的分隔符,從而致使輸入的絕對路徑被解析爲2個參數,最後形成錯誤。這個問題當時我調試了半天仍然沒有獲得解決。所以,Windows下使用movie濾鏡的時候,須要保證水印文件就在當前的工做目錄中,才能正常運行。 
【overlay濾鏡】 
Overlay濾鏡用於疊加兩路輸入。具體到本文的系統中就是疊加水印文件到視頻文件上。它經常使用的有兩個參數:

x:水印左上角的x座標 
y:水印左上角的y座標


通過上述幾個濾鏡的處理,最終就能夠獲得一個分辨率爲640x360,保持寬高比(加黑邊),疊加過水印的視頻。

項目主頁

Simplest Video Website

開源中國:http://git.oschina.net/leixiaohua1020/simplest_video_website

安裝步驟 
1.安裝JavaEE環境: 
(1)下載安裝JDK 
(2)下載安裝Tomcat 
(3)下載安裝MySQL 
2.FFmpeg 
(1)下載而且解壓縮FFmpeg可執行程序 
(2)把FFmpeg的bin目錄(其中包含ffmpeg.exe)添加至系統的"path"環境變量(重要,這樣才能夠在系統任意目錄中使用ffmpeg命令) 
3.複製程序 
(1)修改Webroot\WEB-INF\classes\hibernate.cfg.xml中數據庫的用戶名和密碼 
(2)拷貝WebRoot目錄至Tomcat的webapps目錄,從新取個名字(例如"svw") 
(3)在MySQL中建立數據庫"svw",在其中執行svw.sql,建立數據庫中的表,而且添加測試數據 
4.啓動Tomcat 
5.使用瀏覽器訪問http://localhost:8080/svw

 

http://www.cnblogs.com/xkfz007/p/4517966.html

 

♣FFmpeg是什麼?

FFmpeg組成

下載工具

♣安裝FFmpeg

♣應用到j2ee項目


前言:學習視頻編碼,必定要知道雷霄驊(leixiaohua1020)的專欄 ,偉大的程序員,26歲去世。雷霄驊---巨星隕落。此文多爲摘錄自ffmpeg的文檔。

官網:https://www.ffmpeg.org/

github地址:https://github.com/FFmpeg/FFmpeg

1.FFmpeg是什麼?

  引用 百度百科,FFmpeg是一套能夠用來 記錄、轉換數字音頻、視頻,並能將其轉化爲流的開源計算機程序。採用LGPL或GPL許可證。它提供了錄製、轉換以及流化音視頻的完整解決方案。它包含了很是先進的音頻/視頻編解碼庫libavcodec,爲了保證高可移植性和編解碼質量,libavcodec裏不少code都是從頭開發的。
  FFmpeg在Linux平臺下開發,但它一樣也能夠在其它操做系統環境中編譯運行,包括Windows、Mac OS X等。這個項目最先由Fabrice Bellard發起,2004年至2015年間由Michael Niedermayer主要負責維護。許多FFmpeg的開發人員都來自MPlayer項目,並且當前FFmpeg也是放在MPlayer項目組的服務器上。項目的名稱來自MPEG 視頻編碼標準,前面的"FF"表明"Fast Forward"。
2.FFmpeg組成

    構成FFmpeg主要有三個部分,

    2.1第一部分是四個做用不一樣的工具軟件,分別是:ffmpeg.exe,ffplay.exe,ffserver.exe和ffprobe.exe。

  • ffmpeg.exe:音視頻轉碼、轉換器
  • ffplay.exe:簡單的音視頻播放器
  • ffserver.exe:流媒體服務器
  • ffprobe.exe:簡單的多媒體碼流分析器

    2.2第二部分是能夠供開發者使用的SDK,爲各個不一樣平臺編譯完成的庫。若是說上面的四個工具軟件都是完整成品形式的玩具,那麼這些庫就至關於樂高積木同樣,咱們能夠根據本身的需求使用這些庫開發本身的應用程序。這些庫有:

  • libavcodec:包含音視頻編碼器和解碼器
  • libavutil:包含多媒體應用經常使用的簡化編程的工具,如隨機數生成器、數據結構、數學函數等功能
  • libavformat:包含多種多媒體容器格式的封裝、解封裝工具
  • libavfilter:包含多媒體處理經常使用的濾鏡功能
  • libavdevice:用於音視頻數據採集和渲染等功能的設備相關
  • libswscale:用於圖像縮放和色彩空間和像素格式轉換功能
  • libswresample:用於音頻重採樣和格式轉換等功能

    2.3第三部分是整個工程的源代碼,不管是編譯出來的可執行程序仍是SDK,都是由這些源代碼編譯出來的。FFmpeg的源代碼由C語言實現,主要在Linux平臺上進行開發。FFmpeg不是一個孤立的工程,它還存在多個依賴的第三方工程來加強它自身的功能。在當前這一系列的博文/視頻中,咱們暫時不會涉及太多源代碼相關的內容,主要以FFmpeg的工具和SDK的調用爲主。到下一系列咱們將專門研究如何編譯源代碼並根據源代碼來進行二次開發。

3.下載工具

   在官網上咱們能夠找到"Download"頁面,該頁上能夠下載FFmpeg的工具、庫和源代碼等。在選擇"Windows Packages"下的Windows Builds後,會跳轉到Windows版本的下載頁面:

   

   

   在下載頁面上,咱們能夠看到,對於32位和64位版本,分別提供了三種不一樣的模式:static、shared和dev

  • static: 該版本提供了靜態版本的FFmpeg工具,將依賴的庫生成在了最終的可執行文件中;做爲工具而言此版本就能夠知足咱們的需求;
  • share: 該版本的工具包括可執行文件和dll,程序運行過程必須依賴於提供的dll文件;
  • dev: 提供了庫的頭文件和dll的引導庫;

4.安裝FFmpeg

  4.1 這裏下載的是static版本,將其下載解壓到E:\javaEdit\ffmpeg目錄下:

  

  4.2配置環境變量:E:\javaEdit\ffmpeg\bin;

  

  4.3 dos窗口輸入 ffmpeg -version  命令,若有信息則說明成功:

  

5.應用到j2ee項目:

  最簡單的視頻網站(JavaEE+FFmpeg)

相關文章
相關標籤/搜索