生活随笔
收集整理的這篇文章主要介紹了
Web端 Html5 直接播放 .ts 视频
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
常見方案
在網上查找的大部分解決方案都是用諸如videojs等網頁播放器,接收 .m3u8索引文件的方式來播放ts切片。這種方案的缺點是需要后端對原始ts切片做處理,生成 .m3u8索引文件
ffmpeg -i source.ts -c copy -map 0 -f segment -segment_list playlist.m3u8 -segment_time 10 output%03d.ts
項目中已存儲的 .ts 切片數量眾多,已經占用了NAS服務器絕大部分的資源,生成的 .m3u8 索引雖然非常小,但會生成一堆切片后的新 .ts 視頻,例如上述指令將會生成一堆 10s 長度的 ts新切片。出于各種考慮后端的同學拒絕了這種重新生成新切片加索引的方案。
優雅方案
在中文互聯網搜索無果后,果斷轉向了Google,然而也未果,正當我絕望地準備調整心態,接受下載后VLC播放的保底方案時,終于發現了一絲線索,在vediojs的Github頁面中,Issue1441 和 Issue4297 中,面對videojs能否直接播放 .ts 的疑問,開發團隊都表示雖然庫本身沒有直接的相關實現,但可以利用相關的邏輯自行實現。最重要的是都指出了mux.js這一工具。根據實測,只用這一個庫即可在web端直接播放 .ts 視頻.
代碼示例
示例中是以 ajax 的方式接收 .ts 二進制數據,mux.js引入方式可以直接標簽引入,也可以npm install mux.js后 import進頁面。
var $ = document.querySelector.bind(document);var vjsParsed,video, mediaSource;// 定義通用的事件回調處理函數,只做打印事件類型function logevent (event) {console.log(event);}// ajaxlet xhr = new XMLHttpRequest();xhr.open('GET', "./test.ts");// 接收的是 video/mp2t 二進制數據,并且arraybuffer類型方便后續直接處理 xhr.responseType = "arraybuffer";xhr.send();xhr.onreadystatechange = function () {if (xhr.readyState ==4) {if (xhr.status == 200) {transferFormat(xhr.response);} else {console.log('error');}}}function transferFormat (data) {// 將源數據從ArrayBuffer格式保存為可操作的Uint8Array格式// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffervar segment = new Uint8Array(data); var combined = false;// 接收無音頻ts文件,OutputType設置為'video',帶音頻ts設置為'combined'var outputType = 'video';var remuxedSegments = [];var remuxedBytesLength = 0;var remuxedInitSegment = null;// remux選項默認為true,將源數據的音頻視頻混合為mp4,設為false則不混合var transmuxer = new muxjs.mp4.Transmuxer({remux: false});// 監聽data事件,開始轉換流transmuxer.on('data', function(event) {console.log(event);if (event.type === outputType) {remuxedSegments.push(event);remuxedBytesLength += event.data.byteLength;remuxedInitSegment = event.initSegment;}});// 監聽轉換完成事件,拼接最后結果并傳入MediaSourcetransmuxer.on('done', function () {var offset = 0;var bytes = new Uint8Array(remuxedInitSegment.byteLength + remuxedBytesLength)bytes.set(remuxedInitSegment, offset);offset += remuxedInitSegment.byteLength;for (var j = 0, i = offset; j < remuxedSegments.length; j++) {bytes.set(remuxedSegments[j].data, i);i += remuxedSegments[j].byteLength;}remuxedSegments = [];remuxedBytesLength = 0;// 解析出轉換后的mp4相關信息,與最終轉換結果無關vjsParsed = muxjs.mp4.tools.inspect(bytes);console.log('transmuxed', vjsParsed);prepareSourceBuffer(combined, outputType, bytes);});// push方法可能會觸發'data'事件,因此要在事件注冊完成后調用transmuxer.push(segment); // 傳入源二進制數據,分割為m2ts包,依次調用上圖中的流程// flush的調用會直接觸發'done'事件,因此要事件注冊完成后調用transmuxer.flush(); // 將所有數據從緩存區清出來}function prepareSourceBuffer (combined, outputType, bytes) {var buffer;video = document.createElement('video');video.controls = true;// MediaSource Web API: https://developer.mozilla.org/zh-CN/docs/Web/API/MediaSourcemediaSource = new MediaSource(); video.src = URL.createObjectURL(mediaSource);$('#video-wrapper').appendChild(video); // 將H5 video元素添加到對應DOM節點下// 轉換后mp4的音頻格式 視頻格式var codecsArray = ["avc1.64001f", "mp4a.40.5"];mediaSource.addEventListener('sourceopen', function () {// MediaSource 實例默認的duration屬性為NaNmediaSource.duration = 0;// 轉換為帶音頻、視頻的mp4if (combined) {buffer = mediaSource.addSourceBuffer('video/mp4;codecs="' + 'avc1.64001f,mp4a.40.5' + '"');} else if (outputType === 'video') {// 轉換為只含視頻的mp4buffer = mediaSource.addSourceBuffer('video/mp4;codecs="' + codecsArray[0] + '"');} else if (outputType === 'audio') {// 轉換為只含音頻的mp4buffer = mediaSource.addSourceBuffer('audio/mp4;codecs="' + (codecsArray[1] ||codecsArray[0]) + '"');}buffer.addEventListener('updatestart', logevent);buffer.addEventListener('updateend', logevent);buffer.addEventListener('error', logevent);video.addEventListener('error', logevent);// mp4 buffer 準備完畢,傳入轉換后的數據// 將 bytes 放入 MediaSource 創建的sourceBuffer中// https://developer.mozilla.org/en-US/docs/Web/API/SourceBuffer/appendBufferbuffer.appendBuffer(bytes);// 自動播放// video.play();});};
IE8及以上 、 IE Edge 、Chrome 、 Firefox 瀏覽器下均能正常播放。
轉載至:https://www.jianshu.com/p/4d90f81b01bc
總結
以上是生活随笔為你收集整理的Web端 Html5 直接播放 .ts 视频的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。