jsmpeg视频播放器使用方法和常见问题解决方案
JSMpeg是一个使用JavaScript编写的视频播放器,它可以在浏览器中播放MPEG1视频和MP2音频流。JSMpeg的特点是它能够通过WebSockets实时传输视频流,并且可以在不支持HTML5视频播放器的浏览器上运行。以下是JSMpeg的基本使用方法和一些常见问题的解决方案:
主要用来解决移移动端视频播放问题
a.视频video标签做背景无法自动播放,
b.视频video容易被浏览器自己劫持处理等情况
c.视频横竖屏控制
官网:https://jsmpeg.com/
github:https://github.com/phoboslab/jsmpeg
官方例子:https://jsmpeg.com/perf.html
一、初始化参数和API
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=750, user-scalable=no"> <title>ts视频播放器jsmpeg</title> </head> <body> <script src="js/jsmpeg.min.js"></script> <canvas id="video-canvas" style="width: 750px; height: 422px;"></canvas> <script> //使用方法1 var canvas = document.getElementById('video-canvas'); var url = 'https://files2.changyou.com/vc/dj/2023/1115/loop2.ts'; var player = new JSMpeg.Player(url, { canvas: canvas}); player.play()//播放 console.log(player.volume) function onUnlocked () { player.volume = 1 document.removeEventListener('touchstart', onTouchStart) } function onTouchStart () { player.audioOut.unlock(onUnlocked) document.removeEventListener('touchstart', onTouchStart) } // try to unlock immediately //在使用 jsmpeg 播放音频时,有些浏览器(例如 iOS Safari)会限制自动播放声音。为了解决这个问题,需要先让用户交互一次,然后再播放声音。 //如果没有成功,后面还绑定的有touchstart事件,用户触摸屏后会自动播放声音 player.audioOut.unlock(onUnlocked) // try to unlock by touchstart event //通过touchstart事件,让用户交互一次,解锁声音 document.addEventListener('touchstart', onTouchStart, false) </script> <!-- 使用方法2 ios自动播放data-autoplay="true",视频右下角有解锁声音按钮--> <div class="jsmpeg" style="width: 750px; height: 422px;" data-url="https://files2.changyou.com/vc/dj/2023/1115/loop2.ts" data-autoplay="false"></div> </body> </html>
请注意,使用HTML元素(内部JSMpeg.VideoElement)提供了一些JSMpeg.Player之上的功能。即SVG暂停/播放按钮和在iOS设备上“解锁”音频的能力。 url参数接受一个MPEG .ts文件或WebSocket服务器(ws://...)的URL。 options参数支持以下属性: canvas - 用于视频渲染的HTML Canvas元素。如果没有给出,渲染器将创建自己的Canvas元素。 loop - 是否循环播放视频(仅适用于静态文件)。默认为true。 autoplay - 是否立即开始播放(仅适用于静态文件)。默认为false。audio - 是否解码音频。默认为true。 video - 是否解码视频。默认为true。poster - 在视频播放之前显示的海报图像的URL。 pauseWhenHidden - 标签页处于非活动状态时是否暂停播放。默认为true。请注意,浏览器通常会降低非活动标签页上的JS执行速度。 disableGl - 是否禁用WebGL并始终使用Canvas2D渲染器。默认为false。 disableWebAssembly - 是否禁用WebAssembly并始终使用JavaScript解码器。默认为false。 preserveDrawingBuffer - 是否使用preserveDrawingBuffer创建WebGL上下文 - 对通过canvas.toDataURL()进行“截图”必要。默认为false。 progressive - 是否以块的形式加载数据(仅适用于静态文件)。启用时,可以在整个源完全加载之前开始播放。默认为true。 throttled - 在使用progressive时,是否在播放尚不需要的块时延迟加载。默认为true。 chunkSize - 在使用progressive时,一次加载的块大小(以字节为单位)。默认为10241024(1MB)。 decodeFirstFrame - 是否解码并显示视频的第一帧。可用于设置Canvas大小并将帧用作“海报”图像。在使用autoplay或流媒体源时,此选项无效。默认为true。 maxAudioLag - 在流媒体播放时,音频排队的最大长度(以秒为单位)。 videoBufferSize - 在流媒体播放时,视频解码缓冲区的大小(以字节为单位)。默认为5121024(512KB)。对于非常高的比特率,您可能需要增加这个值。 audioBufferSize - 在流媒体播放时,音频解码缓冲区的大小(以字节为单位)。默认为128*1024(128KB)。对于非常高的比特率,您可能需要增加这个值。 onVideoDecode(decoder, time) - 在每个已解码和渲染的视频帧后调用的回调函数。 onAudioDecode(decoder, time) - 在每个已解码的音频帧后调用的回调函数。 onPlay(player) - 在播放开始时调用的回调函数。 onPause(player) - 在播放暂停时调用的回调函数(例如调用.pause()或源已结束)。 onEnded(player) - 在播放已达到源的末尾时调用的回调函数(仅当loop为false时调用)。 onStalled(player) - 每当没有足够的数据进行播放时调用的回调函数。 onSourceEstablished(source) - 在源首次接收到数据时调用的回调函数。 onSourceCompleted(source) - 在源接收到所有数据时调用的回调函数。 除canvas之外的所有选项也可以通过data-属性与HTML元素一起使用。例如,在JavaScript中指定循环和自动播放: var player = new JSMpeg.Player('video.ts' {loop: true, autoplay: true});或者HTML中 <div class="jsmpeg" data-url="video.ts"data-loop="true" data-autoplay="true"></div>请注意,当作为数据属性使用时, camelCased选项必须使用连字符。例如,decodeFirstFrame: true变为data-decode-first-frame="true"用于HTML元素。 JSMpeg.Player APIJSMpeg.Player实例支持以下方法和属性: .play() - 开始播放.pause() - 暂停播放.stop() - 停止播放并跳转到开头.nextFrame() - 推进一个视频帧的播放。 这不会解码音频。成功返回true,当没有足够的数据时返回false。.volume - 获取或设置音频音量(0-1) .currentTime - 获取或设置当前播放位置(以秒为单位).paused - 只读属性,表示播放是否暂停.destroy() - 停止播放, 断开源连接并清理WebGL和WebAudio状态。之后将无法使用播放器。如果播放器创建了canvas元素,则会从文档中删除它。
二、常见问题和解决方案
1.跨域(同时跨https)加载被浏览器拦截,需要手动Ajax请求加载资源完成后再播放
对视频域名做'Access-Control-Allow-Origin' *; # 无法携带cookie
Ajax的时候可以设置:
xhrFields: {
withCredentials: false //配置后,ajax请求不发送cookie,不会触发跨域预请求(options请求)
},
实际跨域加载视频的时候根据请求报错增加配置,ts播放的时候文件是被切成一段一段加载的,需要下面这属性(nginx配置)
add_header 'Access-Control-Allow-Headers' 'Content-Type,Content-Length,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
这个指令是用于配置 HTTP 响应头中的
Access-Control-Expose-Headers 属性。在跨域资源共享(CORS)中,浏览器限制了响应中可以被 JavaScript 访问的头部信息,只有一些简单的头部(比如
Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma)是允许被暴露给客户端的。
2.移动端视频ios下没有声音,需要再用户触摸屏幕后,调用api设置 player.volume = 1,重新开启声音
function onUnlocked () { player.volume = 1 document.removeEventListener('touchstart', onTouchStart) } function onTouchStart () { player.audioOut.unlock(onUnlocked) document.removeEventListener('touchstart', onTouchStart) } // try to unlock immediately player.audioOut.unlock(onUnlocked) // try to unlock by touchstart event document.addEventListener('touchstart', onTouchStart, false)
3.mp4转换ts方法(前提是已安装:FFmpeg,其他工具也可以转,需要选对格式,选择视频编码器为 MPEG-1 Video):修改如下命令参数,再执行命令
ffmpeg -i in.mp4 -f mpegts -codec:v mpeg1video -s 960x540 -b:v 1500k -r 30 -bf 0 -codec:a mp2 -ar 44100 -ac 1 -b:a 128k out.ts
这是一个使用 FFmpeg 命令行工具进行视频转换的命令,下面是对各个参数的解释: -i in.mp4: 指定输入文件为 in.mp4,这表示要对 in.mp4 进行处理。 -f mpegts: 指定输出格式为 MPEG-TS 格式,MPEG-TS 是一种常见的音视频传输格式。 -codec:v mpeg1video: 指定视频编解码器为 MPEG-1 视频编解码器,用于将输入视频流编码成 MPEG-1 格式。 -s 960x540: 指定输出视频的分辨率为 960x540 像素。 -b:v 1500k: 指定视频的比特率为 1500 kbps,控制视频数据的传输速率。 -r 30: 指定视频的帧率为 30 帧每秒,即视频的播放速度。 -bf 0: 禁用 B 帧,B 帧是视频压缩中的一种技术,这里设置为 0 表示禁用 B 帧。 -codec:a mp2: 指定音频编解码器为 MPEG-1 Audio Layer II (MP2) 编解码器。 -ar 44100: 指定音频的采样率为 44100 Hz,表示每秒采样44100次。 -ac 1: 指定输出音频为单声道。 -b:a 128k: 指定音频的比特率为 128 kbps,控制音频数据的传输速率。 最终的命令将输入的 in.mp4 文件转换为 MPEG-TS 格式的 out.ts 文件,视频使用 MPEG-1 编码, 分辨率为 960x540,比特率为 1500 kbps,帧率为 30 帧每秒,禁用了 B 帧;音频使用 MP2 编码, 采样率为 44100 Hz,单声道,比特率为 128 kbps。 1080*720的分度辨率,用5000K左右比特率 720*576的分辨率,用3500K左右比特率 640*480的分辨率,用1500K左右比特率
先按横竖高度交换设置div宽高父容器(一般默认黑背景),再把父容器旋转90度,
根据视频宽高设置canvas设置合适的宽高比,再根据父容器设置合适宽高上下居中即可。
三、 其他注意事项
1.主流视频解码库
JSMpeg
Broadway.js
ogv.js
经评估JSMpeg支持情况较好
2.视频播放器相关库
Chimee 一套可扩展的H5视频播放器组件化框架 https://chimee.org/
西瓜播放器 https://v2.h5player.bytedance.com/