流媒體及FLV播放器相關知識點
以Action Script 3.0(簡稱AS)開發Browser Player時,需要用NetStream,但現在NetStream.play只支援Http和File兩種協議。上網檢查youtube,tudou和youku,發現他們用的播放協議也都是Http。而以Flash Media Server(簡稱FMS)或Red5作為流媒體伺服器時,它們提供的是RTMP協議,且這兩種流媒體伺服器是專門做過最佳化的。這兩種協議,HTTP和RTMP,有幾點不同:
[@more@](1)用HTTP方式: 先透過IIS 將FLV下載到本地快取,然後再透過NetConnection的本地連線來播放這個FLV,這種方法是播放本地的影片,並不是播放伺服器的影片。因此在本地快取裡可以找到這個FLV。其優點就是伺服器下載完這個FLV,伺服器就沒有消耗了,節省伺服器消耗。其缺點就是FLV會快取在客戶端,對FLV的保密性不好。
(2)用RTMP方式: 透過NetConnection連線到FMS/Red5伺服器,並實時播放伺服器的FLV檔案,這種方式可以任意選擇影片播放點,並不象HTTP方式需要快取完整個FLV檔案到本地才可以任意選擇播放點,其優點就是在本地快取裡是找不到這個FLV檔案的。其優點就是FLV不會快取在客戶端,FLV的保密性好,其缺點就是消耗伺服器資源,連線始終是實時的。
由以上分析可以知道,Http方式是本地播放,而RTMP方式是伺服器實時播放。
二、 AS介紹
AS 自3.0開始採用物件導向的設計,而在執行速度上也有了很大的提高。在物件導向的基礎上,AS也採納了類C#和Java的Package,namespace邏輯組織結構,更方便於RIA的開發。
AS通常可以在3種環境下進行開發。
(1) 文字編輯器和編譯器。
安裝AS的編譯器,利用記事本等文字編輯器進行開發,儲存為AS檔案後進行編譯即可。通常可以利用Ant組織編譯生成swf。
(2) 利用Adobe Flash CS 3進行開發
Adobe將Macromedia併入旗下後,便推出了不同於以往Macromedia Flash 8.0版本號的Adobe Flash CS 3。在Flash CS3中,使用者可以方便的將設計FLASH場景、圖層等同編寫AS指令碼相結合。同時,由於Flash CS3內建了很多Flash控制元件,使用者可以將透過fl.control這個開發包方便的使用這些控制元件。
(3) 利用Flex Builder 3進行開發
這是一種基於Eclipse的IDE,熟悉Eclipse的使用者可以像編寫Java程式一樣來編寫AS。同時Flex Builder 3的主要功能是為基於Flex框架程式提供了良好的開發環境。若需要在Flex Builder 3中AS工程中使用內建的控制元件,首先需要將Flash CS3中的標準庫匯入到場景中,然後釋出成為swc檔案。最後將此swc檔案匯入到AS的編譯路徑中即可。
三、基於AS的Flv Player
(1) 自行編寫Flv Player
編寫Flv Player僅需要對AS相關NetStream操作部分有些瞭解, HTML和JS的基礎知識。下面是一個基本的範例:
package {
import fl.controls.Button;
import flash.display.Sprite;
import flash.events.*;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.text.TextField;
public class Player extends Sprite
{
private var _width:int;
private var _height:int;
private var _stream:NetStream;
private var _connection:NetConnection;
private var _video:Video;
private var _playbackTime:TextField = new TextField();
private var _duration:uint;
private var _info:TextField = new TextField();
private var btStart:Button = new Button();
private var btStop:Button = new Button();
private var btPause:Button = new Button();
private var movie:String = "";
private var status:Boolean = true;
public function Player()
{
initialize();
var param:Object = root.loaderInfo.parameters;
movie = String(param["movie"]);
_info.y = 360;
this.addChild(_info);
}
private function initialize():void{
_connection = new NetConnection();
_connection.connect(null);
_stream = new NetStream(_connection);
_stream.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
_stream.bufferTime = 10;
_video = new Video();
this.addChild(_video);
_video.attachNetStream(_stream);
var client:Object = new Object( );
client.onMetaData = onMetaData;
_stream.client = client;
_playbackTime.y = 300;
addChild(_playbackTime);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
btStart.label = "start";
btStart.y = 300;
btStart.x = 0;
btStart.addEventListener(MouseEvent.CLICK, startButtonAction);
addChild(btStart);
btStop.label = "stop";
btStop.y = 300;
btStop.x = 120;
btStop.addEventListener(MouseEvent.CLICK, stopButtonAction);
addChild(btStop);
btPause.label = "pause";
btPause.y = 300;
btPause.x = 240;
btPause.addEventListener(MouseEvent.CLICK, pauseButtonAction);
addChild(btPause);
}
private function startButtonAction(e:MouseEvent):void{
_stream.play(movie);
}
private function stopButtonAction(e:MouseEvent):void{
_stream.close();
}
private function pauseButtonAction(e:MouseEvent):void{
if(status){
_stream.pause();
status = false;
}else{
_stream.resume();
status = true;
}
}
private function onMetaData(data:Object):void {
_duration = data.duration;
}
private function onEnterFrame(event:Event):void {
if(_duration > 0 && _stream.time > 0) {
_playbackTime.text = Math.round(_stream.time) + " / " +
Math.round(_duration);
}
}
private function onStatus(event:NetStatusEvent):void {
if(_video.videoWidth > 0 && _video.width != _video.videoWidth) {
_width = _video.videoWidth;
_height = _video.videoHeight;
var param:Object = root.loaderInfo.parameters;
var widthString:String = String(param["width"]);
var heightString:String = String(param["height"]);
var width:int = -1;
var height:int = -1;
if(widthString != "undefined"){
width = int(widthString);
}
if(heightString != "undefined"){
height = int(heightString);
}
if(width == -1){
if(height == -1){
_video.width = _width;
_video.height = _height;
}else{
_video.height = height;
_video.width = _width * height / _height;
}
}else{
_video.width = width;
_video.height = _height * width / _width;
}
}
}
}
}
(2) 使用開源的Flv player
推薦使用Flowplayer,可以下載它的原始碼,同樣是利用ant進行編譯。但是需要注意的是,需要進行簡單的修改。
在build.properties檔案中修改MTASC_BIN和SWFMILL_BIN的值
//MTASC_BIN=/opt/mtasc/mtasc
MTASC_BIN=bin/mtasc/mtasc.exe
// You should use swfmill version 0.2.11 (will not work with the newer version)
//SWFMILL_BIN=/usr/local/bin/swfmill
SWFMILL_BIN=bin/swfmill/swfmill.exe
在skinbuild.xml檔案中
value="${SWFMILL_BIN}"
else="${SWFMILL_BIN}">
<!--原來是value="${SWFMILL_BIN_WIN}" else="${SWFMILL_BIN}" -->
將更改後,執行ant即可,就可以得到重新編譯好的flowplayer。
當需要更改播放器皮膚,特別是需要將播放器皮膚提示資訊的英文改為中文,即修改skin.as部分程式碼,這時候就必須要重新編譯了。
四、支援RTMP協議的Red5 Server
Red5是Java實現的一種開源的Flash流媒體伺服器,它支援FLV和MP3格式的Streaming Audio/Video、FLV格式的Recording Client Stream、共享物件、實時流釋出等多種功能。
當使用Red5作為Server時,需要完成客戶端和伺服器端兩部分的工作。在伺服器端,寫自己的應用程式,即rtmp服務的提供。這個應用程式的入口應該extends ApplicationAdapter這個類,然後將它部署到Server上。伺服器端示例程式碼如下:
import org.red5.server.adapter.ApplicationAdapter;
public class Application extends ApplicationAdapter {
public Double add(Double a, Double b){
return a + b;
}
}
在客戶端由AS完成,去訪問伺服器端構造的服務,示例程式碼如下
nc = new NetConnection();
nc.connect("rtmp://localhost/myapp");
nc.onResult = function(obj) {
trace("The result is " + obj);
}
nc.call("add", nc, 1, 2);
這樣就完成了基本的實現了AS透過RTMP協議呼叫Red5 伺服器端所提供的服務。更多的具體內容,可以參考Red5文件去實踐。來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9099175/viewspace-1024676/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- rman配置及常用操作相關知識點
- Git相關知識點Git
- redis相關知識點Redis
- shell相關知識點
- Oracle 相關知識點Oracle
- 【Java】容器相關知識點Java
- ivar layout 相關知識點
- LR模型相關知識點模型
- ARP相關知識點
- React相關知識點:關於ReduxReactRedux
- Java容器相關知識點整理Java
- 總結 MySQL 相關知識點MySql
- JVM相關知識點總結JVM
- UIBarButtonItem的相關知識點UI
- library cache相關知識點
- Extjs相關知識點梳理JS
- tmpwatch相關的知識點
- 信管知識梳理(三)軟體工程相關知識軟體工程
- 網路硬體相關知識
- CDN相關知識及CDN繞過
- 面試系列之View相關知識點面試View
- 資料庫相關知識點提要資料庫
- oracle檢查點的相關知識Oracle
- GreatSQL統計資訊相關知識點SQL
- 關於流媒體的一些常識
- https握手過程及相關知識HTTP
- Fragment 相關知識點都在這裡了Fragment
- PHP物件相關知識點的總結PHP物件
- 異常處理及其相關知識點
- Shell相關知識
- .net相關知識
- mobile相關知識
- rollback相關知識
- 一些關於IO流的知識點
- web跨域及cookie相關知識總結Web跨域Cookie
- 電腦硬體相關簡單知識
- Java併發相關知識點梳理和研究Java
- 資料庫相關知識點(秋招整理)資料庫