h5 video 视频播放开发 和 问题集合
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了h5 video 视频播放开发 和 问题集合相关的知识,希望对你有一定的参考价值。
参考技术A一共支持三种格式: Ogg、MPEG4、WebM。但这三种格式对于浏览器的兼容性却各不同。
重点:比如MP4格式,MP4只是一个容器,里面还有一个叫编码器的东西。格式虽然都是MP4但是html中只支持H.264的编码格式。所以要用软件来转码。
MP4 = MPEG 4文件使用 H264 视频编解码器和AAC音频编解码器
WebM = WebM 文件使用 VP8 视频编解码器和 Vorbis 音频编解码器
Ogg = Ogg 文件使用 Theora 视频编解码器和 Vorbis音频编解码器
补充: 有时会出现视频封面无法铺满的情况,需要使用 object-fit 属性铺满整个屏幕
如果是PC电脑上,完全可以用video标签controlsList属性,修改成如下即可!
//去除右键事件
https://www.jianshu.com/p/23f9dbfab563
https://blog.csdn.net/weixin_45266779/article/details/120990591
https://www.cnblogs.com/congxueda/p/15091316.html
https://www.cnblogs.com/liuxianan/p/html5-video-resize.html
Obj-C中,需要添加配置webview.allowsInlineMediaPlayback = YES;
Swift请查找相关API进行配置。
开发5+App,需要在manifest.json的plus节点下新增allowsInlineMediaPlayback节点为true。
安卓监听进入全屏的事件:
ios监听进入全屏的事件:
SkeyeWebPlayer.js H5播放器开发之播放器video动态创建
SkeyeWebPlayer.js H5播放器是由成都视开信息科技开发和维护的一个完善的RTSP、FLV、HLS等多种流媒体协议播放,视频编码支持H.264,H.265,音频支持AAC,支持TCP/UDP协议,是一套极佳的且适合用于综合安防视频云服务播放组件,已经非常稳定、完整。功能包括:直播、录像、抓图,目前在功能性、稳定性、可扩展性和完整性极强的一款H5播放器!
上一节加到编译flvjs播放器,实现基础的播放器功能,本节将实现自定义动态创建video标签渲染。如下图:
首先为了方便开发,需要将项目的目录结构做以下调整
- 新建flv目录,将之前的flvjs代码放到这个目录内,
- 新建一个element 目录下新建index.js,具体代码:放在下面,
- 首先创建一个 class 类,Element 接受self:(调用this),dom:(播放器容器:由初始化传入ID去获取:document.getElementById(ID))options:height,当然如果有需要其他参数也可以传入,根据自己的需求来即可,
- 首先判断有没dom (播放器容器)
- height:是否继承外部容器的高度 Boolean值 ,false:动态设置播放器容器 56.25% 也就是默认值 16:9,
- createElement js动态创建video标签,设置宽高为容器的宽高
export default class Element
constructor(self, dom, height)
if (!dom)
return ;
if (height)
dom.style.position = relative;
dom.style.backgroundColor = #000000;
dom.style.overflow = hidden;
else
dom.style.position = relative;
dom.style.backgroundColor = #000000;
dom.style.width = 100%;
dom.style.height = 100%;
dom.style.paddingTop = 56.25%;
dom.style.overflow = hidden;
this.elDom = dom;
this.videoEl = document.createElement(video);
this.videoEl.style.width = 100%;
this.videoEl.style.height = 100%;
this.videoEl.style.position = absolute;
this.videoEl.style.top = 0;
this.videoEl.style.left = 0;
this.videoEl.style.background = #000000;
this.videoEl.style.background = #000000;
this.elDom.appendChild(this.videoEl);
// this.videoEl.setAttribute(webkit-playsinline, true);
// this.videoEl.setAttribute(playsinline, true);
在播放器初始化的时候将创建出来video添加到页面
- 在src 目录下index.js 完整代码放在最后面
- import Element from ./element;
- this.videoElement = new Element(this, this.boxDom, height: height );
至此SkeyeWebPlayer播放器之flv播放功能就已经实现
// videoEl
this.videoElement = new Element(this, this.boxDom,
height: height,
isFill: showMode
);
import Features from ./flv/core/features.js;
import ScreenCanvas from ./element/off-screen-canvas;
import Element from ./element;
import BigPlayButton from ./element/big-play-button;
import Emitter from ./utils/emitter;
import isNum, parseLocation from ./utils;
import ./font/iconfont.css;
import ./styles/index.css;
import ./styles/range.css;
import WebFlvPlayer from ./player/webFlvPlayer.js;
export default class WebMediaPlayer extends Emitter
constructor(url, ID, cbFunc, data = )
super();
let cbUserPtr, decodeType, openAudio, bigPlay = false, height = false, showMode = false, playbackRecord = data;
this.player = null;
this.url = url;
this.callbackFunc = cbFunc || function ()
;
this.callbackUserPtr = cbUserPtr;
this.height = height;
this.bigPlay = bigPlay;
this.decodeType = auto;
this.version = __VERSION__;
this.isPlaying = false;
if (decodeType === auto || decodeType === soft)
this.decodeType = decodeType;
if (!Features.supportMSEH264Playback())
this.decodeType = soft;
//此处应为true, 则在所有平台上功能表现正常, 如为false,在苹果上则不能自动播放声音, 现应用在win chrome上,暂置为false;
this.internalTriggerPlay = true;
this.showMode = showMode;
this.playbackRecord = playbackRecord;
this.VideoCodec = ;
this.VideoWidth = 0;
this.VideoHeight = 0;
this.showTimeLabel = false;
this.seeking = false;
this.callbackEnd = false;
this.initH5Flag = false;
this.currentH5Status = false;
this.seekTimeSecs = 0;
this.fullScreenFlag = false;
if (!ID)
return false;
// 声音
this.defaultAudioStatus = !!openAudio;
this.enableAudio = !!openAudio;
this.boxDom = document.getElementById(ID);
if (!this.boxDom)
return false;
// videoEl
this.videoElement = new Element(this, this.boxDom,
height: height,
isFill: showMode
);
this.h5Video = this.videoEl = this.videoElement.videoEl;
// canvas
this.screenCanvas = new ScreenCanvas(this, this.boxDom);
// 中间大播放按钮
this.bigPlayButton = new BigPlayButton(this, this.boxDom, bigPlay);
this.on(streamType, this._onChangeTypeCallback.bind(this));
if (url)
this.play(url, true);
/**
* 播放 play
* @param url
* @param autoPlay
* @param time
* @returns boolean|void
*/
play(url, autoPlay = true, time = 0)
if (!url)
url = this.url;
if (!this.boxDom)
return false;
else if (!url)
return console.log(播放地址不能为空);
else if (!autoPlay)
return false;
else if (!isNum(time))
return console.log(time 必须传数字类型);
let locationObj = parseLocation(url);
if (![rtsp:, http:, https:, ws:, wss:].some(item => item === locationObj.protocol))
console.log(不支持 stream: + url);
this.url = url;
this.emit(play);
this.callbackFunc(play);
this.seekTimeSecs = time;
// 关闭加载动画
this._onConnectStatus(this, 99);
// 后缀
let postfix = url.split(.).pop().toLowerCase();
if (this.player)
// 暂停之后继续播放
this.player.play(this.url, 0);
else if (/flv$/.test(postfix))
// FLV流 (http-flv 、 ws-flv)
this.player = new WebFlvPlayer(this,
type: flv,
isLive: true,
url: url,
videoDom: this.videoEl,
canvasDom: this.screenCanvas.canvas,
decodeType: this.decodeType,
,
onGetVideoInfo: this.onVideoInfo,
self: this
);
stop()
if (!this.boxDom) return;
this.callbackFunc(stop);
this.callbackEnd = false;
this._onConnectStatus(this, 99); // 关闭加载动画
if (this.playerInstance)
this.closeAudio();
this.playerInstance.stop();
this.showTimeLabel = false;
return true;
return false;
pause()
this.player.pause();
removeAllChilds(p)
for (var i = p.childNodes.length - 1; i >= 0; i--)
this.removeAllChilds(p.childNodes[i]);
p.removeChild(p.childNodes[i]);
destroy()
this.stop();
if (this.boxDom)
this.removeAllChilds(this.boxDom);
if (this.playerInstance)
this.playerInstance.stop();
this.playerInstance.destroy();
delete this.playerInstance;
this.playerInstance = null;
changeToH5Video(b)
if (!this.initH5Flag)
this.initH5Flag = true;
else
if (b === this.currentH5Status)
return;
this.currentH5Status = b;
if (b)
if (this.screenCanvas.canvas)
this.boxDom.removeChild(this.screenCanvas.canvas);
else
if (this.h5Video)
this.boxDom.removeChild(this.h5Video);
// 连接状态回调
_onConnectStatus(_this, status)
_this.emit(status, status);
//流类型回调
_onChangeTypeCallback(streamType, isWasm)
this.changeToH5Video(!isWasm);
/**
* 获取视频编码信息
* @param _this
* @param _videoCodec
* @param _width
* @param _height
* @private
*/
onVideoInfo(_this, _videoCodec, _width, _height)
_this.VideoCodec = _videoCodec;
_this.VideoWidth = _width;
_this.VideoHeight = _height;
_this.emit(resolutionRatio, code: _videoCodec, width: _width, height: _height);
_this._onConnectStatus(_this, 100);
rtspScale(scaleValue, ptsInterval)
if (this.playerInstance)
this.playerInstance.rtspScale(scaleValue, ptsInterval);
//外部调用(秒)
seekToSecs(seekValue)
console.log(seekValue, seekValue);
if (this.playerInstance)
this.playerInstance.seek(seekValue, 0);
//百分比
seekToPercent(seekValue)
if (this.playerInstance)
this.playerInstance.seek(seekValue, 1);
// 设置滚动条和时间标签
setTrack(timeTrack, timeLabel)
if (this.playerInstance)
this.playerInstance.setTrack(timeTrack, timeLabel);
openAudio()
this.callbackFunc(openAudio);
if (this.playerInstance)
if (this.playerInstance.openAudio())
//仅为内部判断是否启用音频进行remux
common.SetEnableAudio(true);
this.enableAudio = true;
else
this.enableAudio = false;
this.emit(audio, this.enableAudio);
return this.enableAudio;
closeAudio()
this.callbackFunc(closeAudio);
if (this.playerInstance)
if (!this.enableAudio)
return true;
if (this.playerInstance.closeAudio())
this.enableAudio = false;
else
this.enableAudio = true;
this.emit(audio, this.enableAudio);
return !this.enableAudio;
showStaticsInfo(enable)
if (this.playerInstance == null)
return false;
if (enable)
return this.playerInstance.openStatinfo();
else
return this.playerInstance.closeStatinfo();
return false;
以上是关于h5 video 视频播放开发 和 问题集合的主要内容,如果未能解决你的问题,请参考以下文章