日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

DASH流媒体MPD文件解析

發(fā)布時間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DASH流媒体MPD文件解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

MPD文件本質(zhì)是XML文件,其說明了DASH服務端流媒體視頻切片的相關信息,包含分辨率,大小,幀率等等,因此在DASH客戶端實現(xiàn)的第一步便是解析服務端的MPD文件,其常見結(jié)構如圖所示:

?

MPD文件來源https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd

例如需要解析出的Representation中的id,width和height屬性值(圖例中MPD文件寫法比較復雜,同一<Representation - />標簽中包含的子屬性較多,因此需要調(diào)用xmlPullParser.getAttributeValue()方法遍歷子屬性)。如果一個標簽中僅含有一個屬性,如<name> fupenzi </name>這種,層層調(diào)用如果語句即可解析,參見《Android第一行代碼》。

Android 提供了三種解析XML的方式:SAX(Simple API XML),?DOM(Document Object Model),?Pull?(Android官方推薦)

SAX是一個用于處理XML事件驅(qū)動的“推”模型,?
優(yōu)點是一種解析速度快并且占用內(nèi)存少的xml解析器,它需要哪些數(shù)據(jù)再加載和解析哪些內(nèi)容。?
缺點是它不會記錄標簽的關系,而要讓你的應用程序自己處理,這樣就增加了你程序的負擔。

DOM是一種文檔對象模型,DOM可以以一種獨立于平臺和語言的方式訪問和修改一個文檔的內(nèi)容和結(jié)構。?
優(yōu)點是DOM技術使得用戶頁面可以動態(tài)地變化,如可以動態(tài)地顯示或隱藏一個元素,改變它們的屬性,增加一個元素等,DOM技術使得頁面的交互性大大地增強。?
缺點是DOM解析XML文件時,會將XML文件的所有內(nèi)容以文檔樹方式存放在內(nèi)存中。

PULL解析和SAX解析很相似,PULL解析和SAX解析不一樣的地方是PULL讀取XML文件后觸發(fā)相應的事件調(diào)用方法返回的是數(shù)字,還有PULL可以在程序中控制想解析到哪里就可以停止解析。

DOM方式最直觀和容易理解,但是只適合XML文檔較小的時候使用,而SAX方式更適合在移動終端系統(tǒng)中使用,因為相比DOM占用內(nèi)存少,適合處理比較大的XML文檔,最后的Pull方式使用場合和SAX類似,但是更適合需要提前結(jié)束XML文檔解析的場合。

具體解析過程可參見Android解析XML的三種方式_d_shadow的博客-CSDN博客_android 讀取xml

創(chuàng)建一個應用程序,簡單演示一下MPD文件的PULL方法解析過程,創(chuàng)建項目XMLParser。

依賴

dependencies {implementation fileTree(include: ['*.jar'], dir: 'libs')implementation 'com.android.support:appcompat-v7:27.1.1'implementation 'com.android.support.constraint:constraint-layout:1.1.3'testImplementation 'junit:junit:4.12'compile 'com.squareup.okhttp3:okhttp:3.4.1'//添加OKHTTP依賴庫androidTestImplementation 'com.android.support.test:runner:1.0.2'androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

MainActivity.java編寫如下:

package com.example.xmlparser;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Button;import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Log;
import java.lang.String;
import java.io.StringReader;import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;/*** Created by fupenzi on 2018/12/19.*/public class MainActivity extends AppCompatActivity implements View.OnClickListener {TextView responseText;//聲明一個回應文本顯示對象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button sendRequest = (Button) findViewById(R.id.send_request);responseText = (TextView) findViewById(R.id.response_text);sendRequest.setOnClickListener(this);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.send_request) {
//            sendRequestWithHttpURLConnection();sendRequestWithOkHttp();}}public void sendRequestWithOkHttp() {//利用OKHTTP對MPD文件進行下載new Thread(new Runnable() {@Overridepublic void run() {try {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd")//MPD請求地址.build();Response response = client.newCall(request).execute();//發(fā)送請求并獲取服務端返回數(shù)據(jù)String responseData = response.body().string();//提取返回數(shù)據(jù)中請求的文件,并轉(zhuǎn)化為字符串parseXMLWithPull(responseData); //對請求的文件進行解析} catch (Exception e) {e.printStackTrace();}}}).start();}private void parseXMLWithPull(String xmlData) { //MPD解析方法Represent repres = new Represent();//實例化一個Representation對象String line = "";try {XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); //獲得一個XMLPULL工廠類的實例XmlPullParser xmlPullParser = factory.newPullParser(); //獲得一個XML解析器的實例xmlPullParser.setInput(new StringReader(xmlData));int eventType = xmlPullParser.getEventType();while (eventType != XmlPullParser.END_DOCUMENT) {String nodeName = xmlPullParser.getName();switch (eventType) {// 通過判斷事件類型來選擇執(zhí)行不同的代碼// 開始解析某個結(jié)點case XmlPullParser.START_TAG: {if ("Representation".equals(nodeName)) {//由<Representation開始解析repres.setId(xmlPullParser.getAttributeValue(null, "id"));repres.setWidth(xmlPullParser.getAttributeValue(null, "width"));repres.setHeight(xmlPullParser.getAttributeValue(null, "height"));}break;}// 完成解析某個結(jié)點case XmlPullParser.END_TAG: {if ("Representation".equals(nodeName)) {     //由Representation--/>結(jié)束解析Log.d("Representation", "id is " + repres.getId()+"; width is " + repres.getWidth()+
"; height is " + repres.getHeight()+";");//在調(diào)試窗口logcat打印出屬性值line = line +"ID: "+ repres.getId()+";  WIDTH: "+repres.getWidth()+
";  HEIGHT: "+repres.getHeight()+";\n";//將已經(jīng)遍歷的屬性值連接成一個字符串,并注意換行}break;}default:break;}eventType = xmlPullParser.next();}showResponse(line);//將字符串對象傳入showResponse()方法,打印在UI的TextView} catch (Exception e) {e.printStackTrace();}}private void showResponse(final String response) {//子線程中不允許進行UI操作,因此利用showResponse()方法切換到主線程更新runOnUiThread(new Runnable() {@Overridepublic void run() {responseText.setText(response);//創(chuàng)建一個TextView顯示傳入字符串}});}
}

對于Represent類(數(shù)據(jù)成員id,width,height,方法成員的set(),get()設置)進行編寫:

package com.example.xmlparser;/*** Created by fupenzi on 2018/12/19.*/public class Represent {private String id;private String width;private String height;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getWidth() {return width;}public void setWidth(String width) {this.width = width;}public String getHeight() {return height;}public void setHeight(String height) {this.height = height;}
}

UI界面:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent" ><Buttonandroid:id="@+id/send_request"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Send Request" /><ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent" ><TextViewandroid:id="@+id/response_text"android:singleLine="false"android:layout_width="match_parent"android:layout_height="wrap_content" /></ScrollView></LinearLayout>

運行效果(在調(diào)用SetText()方法時需要注意,以字符串(流)一次性注入需要顯示出來的文本,若多次調(diào)用SetText()分別顯示每次得到的字符串,則會覆蓋前一次調(diào)用后顯示內(nèi)容):

? 發(fā)出請求后:

Android studio調(diào)試臺顯示結(jié)果:

最后一個Representation標簽中的寬度和高度屬性為null,是因為MPD文件的最后一個Representation標簽是對音頻進行說明,因此沒有長寬屬性。

總結(jié)

以上是生活随笔為你收集整理的DASH流媒体MPD文件解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。