1. 程式人生 > >流媒體傳輸知識整理(四)

流媒體傳輸知識整理(四)

(3)事件處理類:RtspServerHandler.java

publicclass RtspServerHandler extends SimpleChannelHandler {

@Override

publicvoid channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)

throws Exception {

// TODO Auto-generated method stub

super.channelOpen(ctx, e);

LOGGER.info("Rtsp伺服器端channel opened :"+ctx.getChannel().getRemoteAddress());

    }

@Override

publicvoid channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)

throws Exception {

// TODO Auto-generated method stub

super.channelConnected(ctx, e);

LOGGER.info("Rtsp伺服器端channel connected");

    }

privatestaticfinal Logger LOGGER = Logger.getLogger(RtspServerHandler.class);

@Override

publicvoid messageReceived(ChannelHandlerContext ctx, MessageEvent e)

throws Exception {

       HttpRequest objMessage = (HttpRequest) e.getMessage();

LOGGER.info("Rtsp伺服器端接收到資料:"+objMessage);

if(objMessage instanceof HttpRequest){

//         DefaultHttpRequest request = (DefaultHttpRequest) objMessage;

//         HttpRequest req = new DefaultHttpRequest(RtspVersions.RTSP_1_0,RtspMethods.PLAY, "shanglenidexindewodexinhaoshangxin.mp3");

//         e.getChannel().write(req);

//         if(request.getContent() instanceof CompositeChannelBuffer){

//            CompositeChannelBuffer ccb = (CompositeChannelBuffer) request.getContent();

//            byte[] b0 = ccb.getBuffer(0).array();

//            System.out.println(Utils.bytesToHex(b0));

//            byte[] b1 = ccb.getBuffer(b0.length).array();

//            System.out.println(Utils.bytesToHex(b1));

//           

//         }

           writeMsg(objMessage,e.getFuture().getChannel());

       }

    }

privatevoid writeMsg(HttpRequest request , Channel channel) throws IOException{

    ChannelBuffer cbuffer = new DynamicChannelBuffer(8192);

//  cbuffer.writeBytes("hello".getBytes(Constants.UTF8ENCODER));

    DefaultHttpResponse response = new DefaultHttpResponse(RtspVersions.RTSP_1_0, RtspResponseStatuses.OK);

if (request.getMethod().equals(RtspMethods.DESCRIBE)) {

LOGGER.info("DESCRIBE,流向:C-->S;引數要求:推薦;功能:檢查演示或媒體物件的描述,也允許使用接收頭指定使用者理解的描述格式。DESCRIBE的答覆-響應組成媒體RTSP初始階段");

       } elseif (request.getMethod().equals(RtspMethods.ANNOUNCE)) {

LOGGER.info("ANNOUNCE,流向:C<-->S;引數要求:可選;功能:當從使用者發往伺服器時,ANNOUNCE將請求URL識別的演示或媒體物件描述傳送給伺服器;反之,ANNOUNCE實時更新連線描述。如新媒體流加入演示,整個演示描述再次傳送,而不僅僅是附加元件,使元件能被刪除");

       } elseif (request.getMethod().equals(RtspMethods.GET_PARAMETER)) {

LOGGER.info("GET_PARAMETER,流向:C<-->S;引數要求:可選;功能:GET_PARAMETER請求檢查RUL指定的演示與媒體的引數值。沒有實體體時,GET_PARAMETER也許能用來測試使用者與伺服器的連通情況");

       } elseif (request.getMethod().equals(RtspMethods.OPTIONS)) {

LOGGER.info("OPTIONS,流向:C<-->S;引數要求:要求;功能:可在任意時刻發出OPTIONS請求,如使用者打算嘗試非標準請求,並不影響伺服器狀態");

       } elseif (request.getMethod().equals(RtspMethods.PAUSE)) {

LOGGER.info("PAUSE,流向:C-->S;引數要求:推薦;功能:PAUSE請求引起流傳送臨時中斷。如請求URL命名一個流,僅回放和記錄被停止;如請求URL命名一個演示或流組,演示或組中所有當前活動的流傳送都停止。恢復回放或記錄後,必須維持同步。在SETUP訊息中連線頭超時引數所指定時段期間被暫停後,儘管伺服器可能關閉連線並釋放資源,但伺服器資源會被預訂");

       } elseif (request.getMethod().equals(RtspMethods.PLAY)) {

LOGGER.info("PLAY,流向:C-->S;引數要求:要求;功能:PLAY告訴伺服器以SEFUP指定的機制開始傳送資料;直到一些SETUP請求被成功響應,客戶端才可釋出PLAY請求。PLAY請求將正常播放時間設定在所指定範圍的起始處,傳送流資料直到範圍的結束處。PLAY請求可排成佇列,伺服器將PLAY請求排成佇列,順序執行");

       } elseif (request.getMethod().equals(RtspMethods.RECORD)) {

LOGGER.info("RECORD,流向:C-->S;引數要求:可選;功能:該方法根據演示描述初始化媒體資料記錄範圍,時標反映開始和結束時間;如沒有給出時間範圍,使用演示描述提供的開始和結束時間。如連線已經啟動,立即開始記錄,伺服器資料請求URL或其他URL決定是否儲存記錄的資料;如伺服器沒有使用URL請求,響應應為201(建立),幷包含描述請求狀態和參考新資源的實體與位置頭。支援現場演示記錄的媒體伺服器必須支援時鐘範圍格式,smpte格式沒有意義");

       } elseif (request.getMethod().equals(RtspMethods.REDIRECT)) {

LOGGER.info("REDIRECT,流向:S-->C;引數要求:可選;功能:重定向請求通知客戶端連線到另一伺服器地址。它包含強制頭地址,指示客戶端釋出URL請求;也可能包括引數範圍,以指明重定向何時生效。若客戶端要繼續傳送或接收URL媒體,客戶端必須對當前連線傳送TEARDOWN請求,而對指定主執新連線傳送SETUP請求");

       } elseif (request.getMethod().equals(RtspMethods.SET_PARAMETER)) {

LOGGER.info("SET_PARAMETER,流向:C<-->S;引數要求:可選;功能:這個方法請求設定演示或URL指定流的引數值。請求僅應包含單個引數,允許客戶端決定某個特殊請求為何失敗。如請求包含多個引數,所有引數可成功設定,伺服器必須只對該請求起作用。伺服器必須允許引數可重複設定成同一值,但不讓改變引數值。注意:媒體流傳輸引數必須用SETUP命令設定。將設定傳輸引數限制為SETUP有利於防火牆。將引數劃分成規則排列形式,結果有更多有意義的錯誤指示");

       } elseif (request.getMethod().equals(RtspMethods.SETUP)) {

LOGGER.info("SETUP,流向:C-->S;引數要求:要求;功能:對URLSETUP請求指定用於流媒體的傳輸機制。客戶端對正播放的流釋出一個SETUP請求,以改變伺服器允許的傳輸引數。如不允許這樣做,響應錯誤為“455 Method Not Valid In This State”。為了透過防火牆,客戶端必須指明傳輸引數,即使對這些引數沒有影響");

       } elseif (request.getMethod().equals(RtspMethods.TEARDOWN)) {

LOGGER.info("TEARDOWN,流向:C-->S;引數要求:要求;功能:TEARDOWN請求停止給定URL流傳送,釋放相關資源。如URL是此演示URL,任何RTSP連線標識不再有效。除非全部傳輸引數是連線描述定義的,SETUP請求必須在連線可再次播放前釋出");

       }

//  HttpResponse response = new DefaultRtspResponse(RtspVersion.RTSP_1_0, RtspResponseStatuses.OK);

//  response.setHeader(RtspHeaders.Names.CONNECTION, RtspHeaders.Values.KEEP_ALIVE);

//  response.setHeader(RtspHeaders.Names.CONTENT_LENGTH, cbuffer.array().length);

//  response.setProtocolVersion(RtspVersions.RTSP_1_0);

//  response.setStatus(RtspResponseStatuses.OK);

//  response.setHeader(RtspHeaders.Names.CSEQ, 5);

//  response.setChunked(true);

//  if(request.getMethod().getName().equals("GET")){

//     shanglenidexindewodexinhaoshangxin.mp3

       FileInputStream in = new FileInputStream("E://shanglenidexindewodexinhaoshangxin.mp3");

       FileChannel fchannel = in.getChannel();

long length = fchannel.size();

       MappedByteBuffer buffer = fchannel.map(FileChannel.MapMode.READ_ONLY, 0, length);

//     ChannelBuffer cbuffer = new DynamicChannelBuffer(8192);//8KB

       cbuffer.writeBytes(buffer);

//     cbuffer.writeBytes(in, 65536);

       response.setHeader(RtspHeaders.Names.CONTENT_LENGTH, cbuffer.array().length);

//     response.setChunked(true);

       response.setContent(cbuffer);

//  StreamSource ss = new StreamSource(new File("E://shanglenidexindewodexinhaoshangxin.mp3"));

//  FileInputStream in = new FileInputStream("E://shanglenidexindewodexinhaoshangxin.mp3");

//  ChunkedStream cs = new ChunkedStream(in);

//  response.setHeader(RtspHeaders.Names.CONTENT_TYPE, ChannelBuffer.class);

//  response.setHeader(RtspHeaders.Names.CONTENT_LENGTH,in.available());

//  response.setHeader(RtspHeaders.Names.RTP_INFO, cs);

//  }

    channel.write(response);

//  channel.write(cs);

//  channel.write(cbuffer);

}

@Override

publicvoid exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)

throws Exception {

super

相關推薦

媒體傳輸知識整理

(3)事件處理類:RtspServerHandler.javapublicclass RtspServerHandler extends SimpleChannelHandler {@Overridep

大資料系列之資料倉庫Hive知識整理Hive的嚴格模式,動態分割槽,排序,事務,調優

1.Hive的嚴格模式Hive提供了一個嚴格模式,可以防止使用者執行那些產生意想不到的不好的影響的查詢。想想看在那麼大的資料量的前提下,如果我們在分割槽上表上使用查詢所有,或是使用了笛卡爾積查詢資料等等不良情況,那得花費我們多少時間和資源成本,Hive在預設情況下會開啟一種模

Java基礎知識整理

顯式 sys 轉換 強制 print pri 字符 parse ger Java開發環境JDK(Java編輯器、Java運行工具(JRE作用)、Java文檔生成工具、Java打包工具) 1.Java是嚴格區分大小寫的。2.Java程序中一句連續的字符串不能分開在兩行書寫,

理論整理

瀏覽器兼容 嵌入 code 整理 ajax 跟蹤 版本號 輕量級 完成 1、Git 和 SVN 之間的區別: 1.GIT是分布式的,SVN不是分布式; (最核心的區別) 2.GIT把內容按元數據方式存儲,而SVN是按文件; 3.GIT分支和SVN的分支不同; 4

【SQL】- 基礎知識梳理 - 存儲過程

var isp spl 更改 option fault 結果 特定 num 存儲過程的概念 存儲過程Procedure是一組為了完成特定功能的SQL語句集合,經編譯後存儲在數據庫中,用戶通過指定存儲過程的名稱並給出參數來執行 存儲過程的好處 A、 存儲過程允許標準組件式編

《HTML5與CSS3權威指南》知識整理1

scrip 自動驗證 視頻 err ide p s sil html5 oca 《HTML5與CSS3權威指南》知識點整理(1) 1、新增標簽 新增語義化標簽。 <header> 定義 section 或 page 的頁眉。 <nav>定義

linux基礎知識總結

基礎知識第四周學習總結 目錄 一.知識脈絡圖二.軟件包管理三.磁盤管理 一.知識脈絡圖 二.軟件包管理 1.軟件組成 二進制應用程序的組成部分: 二進制文件,庫文件,配置文件,幫助文件 庫文件: 庫文件是一個很特殊的存在,他對於很多程序起著支持作用,如果不小心

python---基礎知識回顧模塊sys,os,random,hashlib,re,json,xml,shutil,configparser,logging,datetime,time,集合,堆,雙端隊列,其他

ID 正常 空值 字符 預測 platform OS normal 生成 前提:dir,__all__,help,__doc__,__file__ dir:可以用來查看模塊中的所有特性(函數,類,變量等) >>> import copy >>

Scala筆記整理:Scala面向對象—類詳解2繼承相關

大數據 Scala [TOC] 單例 希望某個類只存在一個使用的對象,而不管有多少個調用者在使用它,就是單例的概念。 Java中的單例 package cn.xpleaf.single; /** * 單例模式-餓漢式(在屬性中先創建好對象,不管是否調用getInstance方法) * @auth

運維工作中經常用到的一些知識總結

Lftp SLA yourls Tomcat多實例 接上篇:http://blog.51cto.com/bobo365/2125159 54、rabbitMQ http://blog.csdn.net/lishaojun0115/article/details/53152255 用戶管理 用戶

ES6知識整理6--Symbol函數

edi sans tap BE undefine tle cti type 很多 (文章會同步到博客園,技術類文章還是該讓搜索引擎察覺比較好)symbol是js的第7種數據類型:7種分別是:undefined、null、boolean(布爾)、string(字符串)、num

ES6知識整理7--Set和Map數據結構

ora ear 踏實 9.png 叠代 數據 edi KS 返回鍵 (文章會同步到博客園,技術類文章還是該讓搜索引擎察覺比較好)Set構造函數初始化一個值不重復的數組,適合做數組去重。2種數組去重的方法:這裏再說下Array.from(),表示以一個類數組||可叠代對象,創

Python基礎班每日整理

運算 不可變 變量 數字 () 關鍵字 能夠 lob 定義 02_Python基礎_day06 字符串的定義字符串就是一串字符,用一對兒單引號或者雙引號括起來 字符串切片切片就是使用索引值,從一個大的字符串中切出小的字符串,適用於字符串、元組、列表。基本語法是 字符串[

spring 官方文件的介面理解整理型別轉換spring例項解析

上篇文章解析了spring型別轉換的介面和他們的分工,怎麼通過設計模式實現轉換功能。 這篇需要些上篇的知識,如果沒有看可以從這兒跳轉spring 官方文件的介面理解整理(三)型別轉換 一、準備新建Maven專案,pom.xml內容如下 <properties>

Android 學習之《Android程式設計權威指南》第二版 程式碼+筆記整理

(程式碼)GeoQuiz最終開發 GeoQuiz應用初步開發 GeoQuiz應用升級開發 解決GeoQuiz應用旋轉恢復第一題的BUG 不展示編譯器自動完成的程式碼,僅提供手動修改或者編寫的程式碼。 省略了先前一些程式碼,可參照上方連結。 升級內容: 增加作弊按鈕,給使用者提

【C語言實現串列埠通訊知識點整理】關於執行緒和程序

轉載:https://www.cnblogs.com/fuchongjundream/p/3829508.html 因為在外部檔案中呼叫結構體沒有用extern修飾,導致獲取不到正確的值,一直糾結線上程上。現在大概總結執行緒和程序的特點: 概念 1、程序(process) 狹義定義:

JAVA面試常問知識總結——集合

先附一張java集合框架圖   下面根據面試中常問的關於集合的問題進行了梳理: Arraylist 與 LinkedList 有什麼不同? 1. 是否保證執行緒安全: ArrayList 和 LinkedList 都是不同步的,也就是不保證執行緒安全; 2. 底

嵌入式 知識積累 之 硬體開發的基本過程

簡單地總結一下硬體開發的基本過程: 1、明確硬體總體需求情況,如CPU處理能力、儲存容量及速度、I/O埠的分配、介面要求、電平要求、特殊電路要求等等。 2、根據需求分析制定硬體總體方案,尋求關鍵器件及相關技術資料、技術途徑和技術支援,充分考慮技術可行性、可靠性和成本控制,並對開發除錯工具提出

MySQL知識整理

   MySQL基礎知識   資料庫相關概念 DB:database,即是資料庫,裡面儲存了有組織的規範資料。 DBMS:database management system,即是資料庫管理系統,簡稱資料庫軟體、資料庫產品,資料庫是通過DBMS建立和

C++ 重點知識梳理 -------- 面向物件

五、面向物件 5.1 面向物件的三大特性 三大特性:封裝,繼承,多型   封裝:封裝是實現面向物件程式設計的第一步,封裝就是將資料或函式等集合在一個個的單元中(我們稱之為類)。封裝的意義在於保護或者防止程式碼(資料)被我們無意中破壞。 繼承:繼承主要實現重用程式碼,節