@jxstjh/jhvideo
Version:
HTML5 jhvideo base on MPEG2-TS Stream Player
124 lines (101 loc) • 4.06 kB
JavaScript
/*
* Copyright (C) 2016 Bilibili. All Rights Reserved.
*
* @author zheng qian <xqq@xqq.im>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Polyfill from './utils/polyfill.js';
import Features from './core/features.js';
import {BaseLoader, LoaderStatus, LoaderErrors} from './io/loader.js';
import MSEPlayer from './player/mse-player.js';
import NativePlayer from './player/native-player.js';
import HLSPlayer from './player/hls-player.js';
import PlayerEvents from './player/player-events.js';
import {ErrorTypes, ErrorDetails} from './player/player-errors.js';
import LoggingControl from './utils/logging-control.js';
import {InvalidArgumentException} from './utils/exception.js';
// here are all the interfaces
// install polyfills
Polyfill.install();
// factory method
function createPlayer(mediaDataSource, optionalConfig, streamtype = 'live') {
let mds = mediaDataSource;
if (mds == null || typeof mds !== 'object') {
throw new InvalidArgumentException('MediaDataSource must be an javascript object!');
}
if (!mds.hasOwnProperty('type')) {
throw new InvalidArgumentException('MediaDataSource must has type field to indicate video file type!');
}
const isLiveStream = streamtype === 'live';
const finalConfig = {
...optionalConfig,
// 1. 核心状态:严格区分监控实时流和历史录像
isLive: isLiveStream,
// 这里允许最大 2.5 秒延迟,降到 0.5 秒就停止追赶,比较平滑。
liveBufferLatencyChasing: isLiveStream,
liveBufferLatencyMaxLatency: 2.5,
liveBufferLatencyMinRemain: 0.5,
// 监控版“抠门”设置:录播最多只往下缓存 45 秒,消耗到剩 15 秒时再继续拉流
lazyLoad: !isLiveStream,
lazyLoadMaxDuration: isLiveStream ? 0 : 45,
lazyLoadRecoverDuration: isLiveStream ? 0 : 15,
// 播过去的画面立刻扔掉,绝不占用宝贵的堆内存!
autoCleanupSourceBuffer: true,
autoCleanupMaxBackwardDuration: isLiveStream ? 10 : 30,
autoCleanupMinBackwardDuration: isLiveStream ? 5 : 15,
// 监控画面 H.265 关键帧偏大,初始设为 384KB 减少扩容开销
enableStashBuffer: true,
stashInitialSize: 384 * 1024,
}
switch (mds.type) {
case 'mse':
case 'mpegts':
case 'm2ts':
case 'flv':
return new MSEPlayer(mds, finalConfig);
case 'hls':
return new HLSPlayer(mds, finalConfig);
default:
return new NativePlayer(mds, finalConfig);
}
}
// feature detection
function isSupported() {
return Features.supportMSEH264Playback();
}
function getFeatureList() {
return Features.getFeatureList();
}
// interfaces
let mpegts = {};
mpegts.createPlayer = createPlayer;
mpegts.isSupported = isSupported;
mpegts.getFeatureList = getFeatureList;
mpegts.BaseLoader = BaseLoader;
mpegts.LoaderStatus = LoaderStatus;
mpegts.LoaderErrors = LoaderErrors;
mpegts.Events = PlayerEvents;
mpegts.ErrorTypes = ErrorTypes;
mpegts.ErrorDetails = ErrorDetails;
mpegts.MSEPlayer = MSEPlayer;
mpegts.NativePlayer = NativePlayer;
mpegts.LoggingControl = LoggingControl;
Object.defineProperty(mpegts, 'version', {
enumerable: true,
get: function () {
// replaced by webpack.DefinePlugin
return __VERSION__;
}
});
export default mpegts;