必威体育Betway必威体育官网
当前位置:首页 > IT技术

MSE(Media Source Extensions)的一点尝试

时间:2019-08-13 00:13:12来源:IT技术作者:seo实验室小编阅读:64次「手机版」
 

mse

最近对于blob这个东西真的是很感兴趣,图片可以是blob,视频可以是blob,直播也可以是blob,感觉很厉害啊。与之紧密联系的MSE(Media Source Extensions)这个概念。研究一波。

Media Source Extensions 允许javaScript动态地为<audio>和<video>创建媒体流,而不再只能是引用一个视频文件的url。这样就极大地丰富了前端对音视频的处理能力,也赋予了其更多灵活性。

从实例上手

我们先从一个普通的mp4的播放形式上进行改造,由文件url的形式改为blob的方式,以加深对MSE的一点理解。

前端部分

代码不多,大概是这样子。注释中大概解释了基本的流程。

// MediaSource的readyState属性表示了其状态,分别有closed,open,ended三种

// closed:MS没有和媒体元素如video相关联。MS刚创建时就是该状态。

// open:source打开,并且准备接受通过sourceBuffer.APPendBuffer添加的数据

// ended:当endOfStream()执行完成,会变为该状态。

export default {
    data() {
        return {
            mediaSource: null,
            sourceBuffer: null,
            mimeType: 'video/mp4;codecs="avc1.42E01E,mp4a.40.2"'
        }
    },
    mounted() {
        // MediaSource.istypesupported('video/webm;codecs="vorbis,vp8"');//是否支持webm 
        // MediaSource.isTypeSupported('video/mp4;codecs="avc1.42E01E,mp4a.40.2"')//是否支持MP4 
        // MediaSource.isTypeSupported('video/mp2t;codes="avc1.42E01E,mp4a.40.2"')//是否支持ts
        // 首先判断一下对视频格式的支持度,MediaSource提供了isTypeSupported方法
        if ('MediaSource' in window && MediaSource.isTypeSupported(this.mimeType)) {
            this.createMediaSource()
        } else {
            this.$message({message: '您的浏览器不支持MediaSource', type: 'warning'})
        }
    },
    methods: {
        createMediaSource() {
	        // 创建MediaSource对象,并使用URL.createObjectURL来创建指向MediaSource对象的URL供video播放
            this.mediaSource = new MediaSource()
            this.$refs.h5video.src = window.URL.createObjectURL(this.mediaSource)
            // 监听sourceopen
            this.mediaSource.addeventlistener('sourceopen', this.onSourceOpen)
        },
        onSourceOpen() {
            let self = this
            // 创建一个新的 SourceBuffer 对象,然后会将它追加到 MediaSource 的 SourceBuffers 列表中。
            this.sourceBuffer = this.mediaSource.addSourceBuffer(this.mimeType)
            // 监听buffer更新结束事件
            this.sourceBuffer.addEventListener('updateend', () => {
	            // 停止stream
                self.mediaSource.endOfStream()
                // 开始播放
                self.$refs.h5video.play()
            })
            this.requestBuffer()
        },
        requestBuffer() {
            let self = this
            // 请求接口去拉流
            this.$http.get('GetStream', null, {responseType: 'arraybuffer'}).then(resp => {
	            // 拉到的流塞进sourceBuffer里。
                self.sourceBuffer.appendBuffer(resp)
            })
        }
    }
}

后端服务

后端服务主要是将一个视频文件以流的形式推给前端。

router.get('/GetStream', function(req, res, next) {
  let filePath = 'public/videos/frag_bunny.mp4'
  res.set('content-Type', 'application/octet-stream');
  fs.createReadStream(filePath).pipe(res)
})

遇到的坑是:一开始用的是自己本地随便找的一个视频文件,结果报错:

Uncaught DOMException: Failed to execute ‘endOfStream’ on ‘MediaSource’: The MediaSource’s readyState is not ‘open’.

原因是该MP4文件不是 framented mp4,不支持这种MSE的播放形式。最后在MDN上找了一个可用的MP4。

这里也提供一个转换的工具,支持将普通MP4转为 framented mp4

Bento4 MP4 & DASH Class Library, SDK and Tools

最后可以看到前端的video已经是用blob在播放了。

blob播放

相关阅读

MediaInfo使用实例(1)

#include "stdafx.h"#include <iostream>#include <iomanip>#include "MediaInfoDLL.h" //Dynamicly-loaded library (.dll or .s

ResourceBundle与Properties读取配置文件

ResourceBundle与Properties的区别在于ResourceBundle通常是用于国际化的属性配置文件读取,Properties则是一般的属性配置文件读取

ResourceExhaustedError的原因及解决方式

在对see in the dark 代码进行测试时,我输入了一张[2848,4256,3]的ARW  sony原始数据图片,运行后出现下面错误:tensorflow.python.f

spring boot datasource hikari 配置说明

hikari cp参数解释在:https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby原文如下:usernameThis property s

【转】/mnt /media /dev 目录区别

/mnt 是被系统管理员使用,手动挂载一些临时媒体设备的目录。/medai 是自动挂载的目录,比如我们的U盘插在ubuntu下回自动挂载,就会

分享到:

栏目导航

推荐阅读

热门阅读