我已经在react-js
中创建了一个组件,用于使用mediaElement播放hls.js
视频。该组件用于在同一屏幕上显示多个播放器。但效果不理想。
错误仅在iPad上发生:
错误1 :控制台错误“播放已中断”。
AbortError: The play() request was interrupted by a call to pause()
错误2 :有时视频缓冲区已停止(仅在iPad上发生)。
import React, { PureComponent } from 'react';
import flvjs from 'flv.js';
import hlsjs from 'hls.js';
import 'mediaelement';
import utils from '../Util/Util';
import 'mediaelement/build/mediaelementplayer.min.css';
import 'mediaelement/build/mediaelement-flash-video.swf';
class MediaElement extends PureComponent {
state = {
playerId: Date.now()
}
playMedia = async (media) => {
if (media != undefined && media != null) {
try {
console.log('video start playMedia ')
await media.play();
} catch (err) {
console.log('video start playMedia err')
console.log(err)
}
}
}
success(media, node, instance) {
let mediaInstance = media;
let url = mediaInstance.src;
this.playMedia(media)
console.log('success')
if (mediaInstance) {
mediaInstance.addEventListener('play', () => {
console.log('video start play')
}, false);
mediaInstance.addEventListener('ended', () => {
console.log('video start ended')
this.playMedia(media)
}, false);
mediaInstance.addEventListener('pause', () => {
console.log('video start pause')
this.playMedia(media)
}, false);
if (window.Hls) {
mediaInstance.hlsPlayer.on(window.Hls.Events.MANIFEST_PARSED, (event, data) => {
console.log("manifest loaded, found MANIFEST_PARSED");
this.playMedia(media)
});
}
if (mediaInstance.hlsPlayer && mediaInstance.hlsPlayer.addListener) {
console.log(`mediaInstance.hlsPlayer.addListener`);
mediaInstance.hlsPlayer.addListener('hlsError', (e, data) => {
switch (data.type) {
case window.Hls.ErrorTypes.NETWORK_ERROR:
// try to recover network error
console.log(`NETWORK_ERROR`);
if (data.details === window.Hls.ErrorDetails.MANIFEST_LOAD_ERROR || data.details === window.Hls.ErrorDetails.MANIFEST_LOAD_TIMEOUT || data.details === window.Hls.ErrorDetails.MANIFEST_PARSING_ERROR) {
console.log(`data.details === window.Hls.ErrorDetails.MANIFEST_LOAD_ERROR`);
if (mediaInstance != undefined && mediaInstance != null) {
console.log(` data.details === window.Hls.ErrorDetails.MANIFEST_LOAD_ERROR mediaInstance`);
mediaInstance.hlsPlayer.loadSource(url)
}
}
else {
if (mediaInstance != undefined && mediaInstance != null) {
console.log(` data.details === window.Hls.ErrorDetails.MANIFEST_LOAD_ERROR mediaInstance != undefined && mediaInstance != null`);
mediaInstance.hlsPlayer.startLoad()
}
}
break
case window.Hls.ErrorTypes.MEDIA_ERROR:
console.log(`hlsjs: trying to recover from media error, evt ${e}, data ${data} `);
this.playMedia(media)
break;
default:
console.log(`default `);
this.playMedia(media)
break
}
})
}
}
}
error(media, node) {
console.log('error section');
media && console.log(JSON.stringify(media));
if (media != undefined && media != null && media && media.detail && media.detail.target && media.detail.target.hlsPlayer) {
console.log(`error section media`);
media.detail.target.hlsPlayer.startLoad();
}
}
render() {
let props = this.props;
let { playerId } = this.state;
return props.url ? <div key={playerId} className="player-area default-videoContainer-height">
<video id={`react-hls-${playerId}`} preload={'auto'} width={'100%'} autoPlay height={'100%'} loop={false} playsInline webkit-playsinline="true">
<source src={props.url} type={props.type} />
</video>
</div> : null
}
componentDidMount() {
const { MediaElementPlayer } = global;
let { playerId } = this.state;
if (!MediaElementPlayer) {
return;
}
let id = document.getElementById(`react-hls-${playerId}`);
const options = Object.assign({}, {
pluginPath: 'https://cdnjs.com/libraries/mediaelement/',
shimScriptAccess: 'always',
pauseOtherPlayers: false,
features: ['chromecast'],
// if set, overrides <video width>
videoWidth: -1,
// if set, overrides <video height>
videoHeight: -1,
enableAutosize: true,
iPadUseNativeControls: false,
// force iPhone's native controls
iPhoneUseNativeControls: false,
// force Android's native controls
AndroidUseNativeControls: false,
framesPerSecond: 25,
enablePluginDebug: false,
autoRewind: false,
castIsLive: true,
hls: {
autoStartLoad: true
},
// width of audio player
success: (media, node, instance) => this.success(media, node, instance),
error: (media, node) => this.error(media, node)
});
window.flvjs = flvjs;
// window.Hls = hlsjs; // close for local test
this.setState({
player: new MediaElementPlayer(id, options)
});
}
componentWillUnmount() {
if (this.state.player) {
this.state.player.media.remove();
this.setState({ player: null });
console.log(`error componentWillUnmount`);
}
}
}
export default MediaElement;