現(xiàn)如今網(wǎng)絡(luò)上的視頻大多數(shù)都是m3u8格式的,使用m3u8格式有以下好處
1. 方便切換碼率,例如從高清轉(zhuǎn)到藍光
2. 節(jié)約流量,m3u8實際切割成一段段的TS后綴視頻,傳統(tǒng)請求是把整個文件流返回去,網(wǎng)絡(luò)不好或者文件過大時,都會造成響應(yīng)緩慢,m3u8則是返回一個個的ts文件,當(dāng)前ts緩存完才會自動請求下一個ts,ts切割的很小,所以,幾乎是秒響應(yīng)
3 防盜,m3u8可以對ts文件加密,其他就不知道
下面介紹如何下載m3u8
本次介紹一個下載框架,aria官方文檔??1.1 開始 · Aria 使用指南 (laoyuyu.me)
需要在app.build引入aria
implementation 'me.laoyuyu.aria:core:3.8.16' annotationProcessor 'me.laoyuyu.aria:compiler:3.8.16' implementation 'me.laoyuyu.aria:m3u8:3.8.16'
引入完成后,可以使用以下代碼下載文件,,如果是mp4或者圖片,可以使用以下代碼下載,下載代碼:
Aria.download(this).register();//注冊aria
long taskId = Aria.download(SingleTaskActivity.this)
? ? ? ? .load(url) // 下載地址
? ? ? ? .setFilePath(filePath) // 設(shè)置文件保存路徑
? ? ? ? .create();
如果是m3u8,需要重寫IBandWidthUrlConverter和IVodTsUrlConverter,先說說m3u8,我們打開一個m3u8,發(fā)現(xiàn)他是一個索引文件,記錄下一個m3u8的碼率,下一個m3u8則記錄對應(yīng)的ts文件,如下
?但是有這樣3三種情況,
1. 記錄的碼率文件是全路徑路徑,如:https://xxx.com/xxx/index.m3u8
2. 記錄的碼率是相對路徑,如 xxx/index.m3u8(上圖就是這種情況)
3.?記錄的碼率只要文件名,如 index.m3u8
那么aria就不知根據(jù)那種規(guī)則下載,所以我們要重寫IBandWidthUrlConverter,同理Ts文件也一樣,也要重寫IVodTsUrlConverter
重寫IBandWidthUrlConverter:
public class M3U8_Converter implements IBandWidthUrlConverter { @Override public String convert(String m3u8Url, String bandWidthUrl) { System.out.println("m3u8Url:"+m3u8Url); System.out.println("bandWidthUrl:"+bandWidthUrl); //m3u8Url:第一個m3u8,連接到下一個m3u8 //bandWidthUrl:第二個m3u8,包含不同碼率的ts視頻 /*第二個m3u8有些文件帶有全路徑,如:http://xxxx.xxx.com/xxx *有些沒有,如:/20210927/3oCoCiM4/hls/index.m3u8 *因此需要區(qū)分,區(qū)分規(guī)則如下: * 如果包含有http或者https,一定是全路徑,直接訪問 * 如果沒有則是用域名+第二個文件路徑,如:(域名)http://xxxx.xxx.com/20210927/3oCoCiM4/hls/index.m3u8(路徑) */ if(bandWidthUrl.contains("http://")||bandWidthUrl.contains("https://")){ return bandWidthUrl; }else{ //獲取域名 URL url = new URL(m3u8Url); String host=url.getProtocol()+"://"+url.getHost()+":"+url.getDefaultPort(); return host+"/"+bandWidthUrl; } }
重寫IVodTsUrlConverter
public List<String> convert(String m3u8Url, List<String> tsUrls) { System.out.println("m3u8Url:"+m3u8Url); System.out.println("tsUrls:"+tsUrls); //m3u8Url:m3u8文件,包含ts文件 //tsUrls:所有的ts文件 /*某些ts文件帶有全路徑,如:http://xxxx.xxx.com/xxx.ts *有些沒有只有相對路徑,如:/20210927/3oCoCiM4/hls/xx.ts * 有些只有文件名,如:xxx.ts *因此需要區(qū)分,區(qū)分規(guī)則如下: * 如果包含有http或者https,一定是全路徑,直接訪問 * 如果只有相對則是用域名+ts文件路徑,如:(域名)http://xxxx.xxx.com/20210927/3oCoCiM4/hls/0.ts(路徑) * 如果只有文件名,則是1 截取0到xxx.m3u8(不包含)的路徑 2加上ts文件名,如: * http://xxxx.xxx.com/20210927/3oCoCiM4/index.m3u8 * 去掉路徑中xxx.m3u8的路徑 * http://xxxx.xxx.com/20210927/3oCoCiM4/ * 加上ts文件名 */ List<String> newTslist=new ArrayList<>(); String pattern="[0-9a-zA-Z]+[.]ts"; Pattern r = Pattern.compile(pattern); for (int i = 0; i < tsUrls.size(); i++) { String tspath=tsUrls.get(i); Matcher m = r.matcher(tspath); //全路徑 if(tspath.contains("http://")||tspath.contains("https://")){ newTslist.add(tspath); } //只有文件名 else if(m.find()){ int e=m3u8Url.lastIndexOf("/")+1; newTslist.add(m3u8Url.substring(0,e)+tspath); } //相對路徑 else{ String host=Host.gethost(m3u8Url); newTslist.add(host+"/"+tspath); } } return newTslist; }
重寫完這兩個類,我們啟動下載時,就會根據(jù)我們重寫的規(guī)則進行訪問
啟動下載
Aria.download(this).register();//注冊aria M3U8VodOption option = new M3U8VodOption(); // 創(chuàng)建m3u8點播文件配 option.setUseDefConvert(false);//必須設(shè)置false,否則不會使用你重寫那兩個類 option.setBandWidthUrlConverter(new M3U8_Converter()); option.setVodTsUrlConvert(new TS_Converter()); option.generateIndexFile(); long taskId = Aria.download(Activity_Home.context) .load("m3u8的下載路徑") .setFilePath("保存路徑", true) // 設(shè)置點播文件保存路徑,true表示,如果當(dāng)前目錄有文件,則覆蓋相同的文件 .m3u8VodOption(option) // 調(diào)整下載模式為m3u8點播 .create();
接下來是幾個注解
//任務(wù)開始時
@Download.onTaskStart void taskStart(DownloadTask task) {}
//任務(wù)運行時
@Download.onTaskRunning void running(DownloadTask task) {}
//任務(wù)停止時?
@Download.onTaskStop void taskStop(DownloadTask task) {}
//下載失敗時
@Download.onTaskFail void taskFail(DownloadTask task) {}
//下載完成時
@Download.onTaskComplete void taskComplete(DownloadTask task) {}
//任務(wù)刪除時
@Download.onTaskCancel void taskCancel(DownloadTask task) {}
其中DownloadTask有以下方法
DownloadTask.getPercent(); //下載進度 DownloadTask.getSpeed();//下載速度,原始數(shù)據(jù),需要手動轉(zhuǎn)為mb/s,kb/s DownloadTask.getConvertFileSize();//文件大小,已處理單位,自動為xxmb或者xxgb DownloadTask.getConvertCurrentProgress();//已下載的文件大小,單位已處理
具體用法可以參考官方文檔
這樣m3u8就下載好了,我們可以在@Download.onTaskRunning void running(DownloadTask task) {}中監(jiān)聽下載進度等,具體可以根據(jù)實際業(yè)務(wù)開發(fā)
接下來我們講講m3u8的播放,網(wǎng)絡(luò)m3u8可以直接賦值給videoview,也可以正常播放,我們理所當(dāng)然的認為下載到本地的m3u8也可以賦值給videoview,然后正確的播放,但是,事實上,我們把本地路徑賦值給videoview,不能正確播放,會出現(xiàn)該視頻無法播放,那么怎么解決呢,m3u8格式只支持網(wǎng)絡(luò)播放,那么我們把本地路徑換為本地網(wǎng)絡(luò)路徑就可以解決,如http://127.0.0.1:80/index.m3u8,需要本地搭建webservice,搭建步驟如下:
引入nanohttpd
implementation 'org.nanohttpd:nanohttpd:2.3.1'
然后繼承實現(xiàn)NanoHTTPD
public class MyServer extends NanoHTTPD { public static String M3U8="application/x-mpegURL"; public static String Video="video/mp4"; public static String text="video/mp4"; public static String TS="video/mp2t"; public MyServer(int port) { super(port); } public MyServer(int port,Context context) { super(port); } public MyServer(String hostname, int port) { super(hostname, port); } @Override public Response serve(IHTTPSession session) { try { //文件下載得保存路徑 String path = "/storage/emulated/0/Android/data/com.example.iflq/files/Download/"; //本地地址轉(zhuǎn)為網(wǎng)絡(luò)地址 if (session.getUri().contains(path)) { File f = new File(session.getUri()); FileInputStream inputStream = new FileInputStream(f); return newFixedLengthResponse(Response.Status.OK, M3U8, inputStream,f.length()); } //默認頁面 String msg = "<html><body><h1>Hello server</h1></body></html>"; return newFixedLengthResponse(msg); }catch (Exception e){ e.printStackTrace(); String msg = "<html><body><h1>服務(wù)器出錯</h1></body></html>"; return newFixedLengthResponse(msg); } } }
啟動webservice
MyServer mMyServer = new MyServer(8080); try { mMyServer.start(); } catch (IOException e) { e.printStackTrace(); }
這時候我們就可以把m3u8賦值給videoview了,videoView.setVideoPath("http://127.0.0.1:8080/index.m3u8");
注意文件路徑(必須存在,否則一樣不能播放),注意文件的返回格式(application/x-mpegURL)
效果:
如果我說的不夠明白,歡迎提問,如果有錯漏,歡迎指出文章來源:http://www.zghlxwxcb.cn/news/detail-419670.html
來都來了,留個評論唄,點個贊唄文章來源地址http://www.zghlxwxcb.cn/news/detail-419670.html
到了這里,關(guān)于安卓實現(xiàn)M3U8文件的下載和播放的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!