標籤:優點 mave and class seo pen operation 方法 視頻解碼
前言
跳過廢話,直接看本文
當年入坑java是因為它的跨平台優勢。那時我認為,”編寫一次,處處運行。”這聽上去多麼牛逼,應該是所有語言發展的終極之道,java勢必會一統天下。
然而事實證明,那時的我還是太年輕。
正所謂魚和熊掌不可兼得,若要享受跨平台帶來的方便,便不可避免地要接受效能上的不足。事實上,java一直在致力於提高虛擬機器的效能(JIT等技術),但面對對即時計算效能要求很高或涉及到用硬體最佳化的任務(視頻的硬體編碼、解碼)時,仍遠遠比不上c或c++。因此,很少能夠看到有人用java來寫這類軟體。
回到正題,要想寫一個視頻播放器,勢必要處理不同的視頻格式(mp4、avi、rmvb、flv等)。每一類格式的視頻都必須要有對應的解碼器才能播放。絕大多數解碼器的庫都是基於效率高的c或c++寫成的,用java的寫解碼器的庫非常少。
因此,要想用java寫一個視頻播放器,只有以下兩個選擇:
- 使用純java編寫,自己編寫主流視頻格式的軟體解碼器、結合Java媒體架構(JMF)完成視頻解碼任務。
- 使用jni調用現有的c或c++的解碼器庫,完成視頻解碼任務
使用java自己編寫軟體解碼器的優點是能夠真正地實現跨平台,也能很方便靈活地與swing架構結合。然而缺點是太過麻煩,先不說軟體解碼器的效率問題,各種主流視頻格式的解碼器的車輪能否成功地重造都是一個值得商榷的問題。
因此,我採用了第二種辦法,通過jni調用現有的第三方視頻解碼庫來完成視頻解碼的任務,而視頻的顯示、控制的邏輯則交由java來完成。這樣便能夠實現一個效率較高的視頻播放器。值得一提的是,雖然根據平台類型來調用不同平台也能夠實現跨平台,但是會受到諸多限制,這是不可避免的。
接下來便來看看具體怎麼實現一個視頻播放器吧。
本文解碼器的選擇
視頻格式有很多,解碼器也有很多,因此要分別尋找對應的解碼器並封裝成jni介面進行調用是一個繁瑣的任務,因此我們可以找一個已經封裝了多種主流解碼器的ApsaraVideo for Media Processing架構(視頻播放器)的庫來直接進行調用。VLC是一個非常好的選擇。
VLC media player VLC 是一款自由、開源的跨平台多媒體播放器及架構,可播放大多數多媒體檔案,以及 DVD、音訊 CD、VCD 及各類流媒體協議。
在vlc的庫上,我們要用jni進行一定的封裝,從而能用java來調用視頻的解碼和播放控制介面。好在我們不必重造車輪。vlcj是一位國外開發人員用java開發的一個ApsaraVideo for Media Processing架構,底層使用的正是vlc播放器,通過jni調用vlc來完成音訊解碼任務。
開發流程
- 安裝VLC Media Player(我安裝的版本是2.2.4,最好安裝到預設目錄)
- 建立普通maven項目,添加vlcj的依賴
<dependency> <groupId>uk.co.caprica</groupId> <artifactId>vlcj</artifactId> <version>3.10.1</version> </dependency>
接下來就是代碼乾貨了,將會介紹三個項目,都是基於這個vlcj的視頻播放器。
入門樣本
這是vlcj作者提供的入門樣本程式,能夠快速實現一個簡單的視頻播放器,當然,僅僅是播放而已,不提供控制功能。
這裡用的vlcj中提供的內嵌視頻播放組件EmbeddedMediaPlayerComponent,通過其中的mediaPlayer中的playMedia方法可以直接播放視頻,視頻會渲染到EmbeddedMediaPlayerComponent上。EmbeddedMediaPlayerComponent這個組件中提供了很多其他功能,若要實現一個普通的視頻播放器,瞭解這個組件便足夠了。
代碼
package tutorial;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.JFrame;import javax.swing.SwingUtilities;import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;import uk.co.caprica.vlcj.discovery.NativeDiscovery;public class Tutorial { private final JFrame frame; private final EmbeddedMediaPlayerComponent mediaPlayerComponent; public static void main(final String[] args) { new NativeDiscovery().discover(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Tutorial(args); } }); } public Tutorial(String[] args) { frame = new JFrame("My First Media Player"); frame.setBounds(100, 100, 600, 400); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { mediaPlayerComponent.release(); System.exit(0); } }); mediaPlayerComponent = new EmbeddedMediaPlayerComponent(); frame.setContentPane(mediaPlayerComponent); frame.setVisible(true); mediaPlayerComponent.getMediaPlayer().playMedia(args[0]); }}
vlcj-player
這是vlcj作者自己基於vlcj寫的一個開源播放器,功能很全面,完全可以用來作為平時的視頻播放器來使用。由於這個項目內容較多,不便將代碼列出。
項目地址詳見https://github.com/caprica/vlcj-player
javaplayer
這個是我基於vlcj寫的一個簡單的視頻播放器,支援一些簡單的視頻播放控制功能和播放彈幕的功能。
開發這個播放器是出於對java編寫視頻播放器的好奇心,因此沒有提供比較完善的功能,畢竟耗時耗力。只是結合了我之前寫過的一個彈幕播放器,為這個視頻播放器添加了彈幕播放的功能,方便能在播放本地視頻的過程中播放b站的彈幕。
項目地址詳見https://github.com/clayandgithub/javaplayer
後記
在開發過程中遇到一些坑,如視頻渲染組件的透明問題,以及swing的重繪機制導致的一些介面顯示上的bug。有些完全解決了,有些則只是採用曲線救國的方法解決的。如果你在開也遇到了這些問題,歡迎一起交流探討。
附:vlcj的官方文檔
用JAVA寫一個視頻播放器