Files
EasyPlayerJs/html-demo/demo.html
2024-08-01 16:32:01 +08:00

568 lines
22 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>EasyPlayer.js播放器</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="./js/easyplayer-pro.js"></script>
<script src="./demo.js"></script>
</head>
<body>
<div class="container">
<div>
<h5 class="text-lowercase text-bold">EasyPlayer.js播放器</h5>
</div>
<div class="mt-2">
<div class="row">
<div class="col-md-8">
<div id="video" style="background-color: black;aspect-ratio: 16 / 9;"></div>
</div>
<div class="col-md-4">
<p class="text-uppercase fw-bold">配置信息</p>
<div class="decoding row border-bottom mb-2 px-3">
<div class="form-check col">
<input class="form-check-input" type="checkbox" role="switch" id="useMSE" checked>
<label class="form-check-label" for="useMSE">MSE(硬解)</label>
</div>
<div class="form-check col">
<input class="form-check-input" type="checkbox" role="switch" id="useWCS">
<label class="form-check-label" for="useWCS">WCS(硬解)</label>
</div>
<div class="form-check col">
<input class="form-check-input" type="checkbox" role="switch" id="useSIMD">
<label class="form-check-label" for="useSIMD">WASM(软解)</label>
</div>
</div>
<div class="buffer row mb-2 border-bottom px-3">
<div class="form-check col-6">
<input class="form-check-input" type="checkbox" role="switch" id="networkDelayTimeoutReplay"
checked>
<label class="form-check-label" for="networkDelayTimeoutReplay">校时追帧</label>
</div>
<div class="form-check col-6">
<input class="form-check-input" type="checkbox" role="switch" id="replayUseLastFrameShow"
checked>
<label class="form-check-label" for="replayUseLastFrameShow">重播使用上一帧</label>
</div>
<div class="form-check col">
<input class="form-check-input" type="checkbox" role="switch" id="websocket1006ErrorReplay"
checked>
<label class="form-check-label" for="websocket1006ErrorReplay">WebSocket重连</label>
</div>
<div class="form-check col">
<input class="form-check-input" type="checkbox" role="switch" id="hasAudio" checked>
<label class="form-check-label" for="hasAudio">渲染音频</label>
</div>
</div>
<div class="mb-2 border-bottom">
<div class="form-group col-12 mb-2">
<label for="heartTimeout">超出时间无数据重连(s)</label>
<input type="text" class="form-control" id="heartTimeout" value="7" placeholder="如 357">
</div>
<div class="form-group col-12">
<label for="videoBufferDelay">达到延迟重播(s)</label>
<input type="text" class="form-control" id="videoBufferDelay" value="3"
placeholder="如 357">
</div>
<div class="form-group col-12">
<label for="fullscreenWatermarkConfig">水印</label>
<input type="text" class="form-control" id="fullscreenWatermarkConfig" value="EasyPlayer.js"
placeholder="如357">
</div>
<div class="form-group col-12">
<label for="background">封面</label>
<input type="text" class="form-control" id="background" value=""
placeholder="如https://xxx.png">
</div>
<div class="form-group col-12">
<label for="playHref">URL</label>
<input type="text" class="form-control" id="playHref"
value=""
placeholder="如http://,https://,ws://,webrtc://">
</div>
</div>
<div class="mb-2 border-bottom">
<div>
<button type="button" class="btn btn-primary" id="play">播放</button>
<button type="button" class="btn btn-warning text-white" id="rePlay">重播</button>
<button type="button" class="btn btn-danger" id="destroy">销毁</button>
</div>
</div>
</div>
</div>
</div>
<div class="mt-3">
<h5>介绍:</h5>
<div>1. 支持ws-flv, http-flv, hls, webrtc </div>
<div class="text-warning">2. WebRTC使用方式webrtc://xxx </div>
<div>3. 使用时出现跨域请下载文件到本地调试</div>
<div>4. 当浏览器不支持 MSE硬解 时,会自动切换成 WASM软解</div>
<div>5. 关闭音频渲染可以节省性能</div>
<div>6. 支持 电子放大; </div>
<div>7. 支持 水印(动态水印、幽灵水印);</div>
<div>8. 支持 显示上一个视频最后一帧;</div>
<div>9. 支持 播放器快照截图;</div>
<div>10.支持 视频录制(WebM格式(音频+视频)、MP4格式(视频),FLV格式(音频+视频));</div>
<div>11.支持 超时、断网重连、异常暂停播放等;</div>
</div>
<div class="mt-3">
<h5>属性配置</h5>
<table class="table table-bordered">
<thead class="thead-light">
<tr>
<th>属性</th>
<th>说明</th>
<th>类型</th>
<th>默认值</th>
</tr>
</thead>
<tbody>
<tr>
<td>container</td>
<td>播放器容器</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>decoder</td>
<td>wasm解码地址</td>
<td>String</td>
<td>-</td>
</tr>
<tr>
<td>isResize</td>
<td>是否拉伸</td>
<td>Boolean</td>
<td>true</td>
</tr>
<tr>
<td>loadingText</td>
<td>加载显示的文字</td>
<td>String</td>
<td>加载中</td>
</tr>
<tr>
<td>videoBuffer</td>
<td>设置最小缓冲时长,单位秒,播放器会自动消除延迟</td>
<td>Number</td>
<td>1</td>
</tr>
<tr>
<td>hasAudio</td>
<td>是否解析音频</td>
<td>Boolean</td>
<td>true</td>
</tr>
<tr>
<td>useMSE</td>
<td>MSE模式</td>
<td>Boolean</td>
<td>false</td>
</tr>
<tr>
<td>useWCS</td>
<td>WCS模式</td>
<td>Boolean</td>
<td>false</td>
</tr>
<tr>
<td>useSIMD</td>
<td>强制使用wasm模式</td>
<td>Boolean</td>
<td>false</td>
</tr>
<tr>
<td>background</td>
<td>视频封面图片</td>
<td>String</td>
<td>-</td>
</tr>
<tr>
<td>qualityConfig</td>
<td>配置清晰度</td>
<td>Array</td>
<td>['普清', '高清', '超清', '4K', '8K']</td>
</tr>
<tr>
<td>defaultStreamQuality</td>
<td>默认显示的清晰度,如果不设置,会显示第一个清晰度</td>
<td>String</td>
<td>-</td>
</tr>
<tr>
<td>isNotMute</td>
<td>是否渲染音频</td>
<td>Boolean</td>
<td>false</td>
</tr>
<tr>
<td>recordType</td>
<td>视频录制默认mp4格式</td>
<td>String</td>
<td>mp4, flv</td>
</tr>
<tr>
<td>playbackForwardMaxRateDecodeIFrame</td>
<td>录像倍数</td>
<td>Number</td>
<td>-</td>
</tr>
<tr>
<td>debug</td>
<td>控制台日志打印</td>
<td>Boolean</td>
<td>false</td>
</tr>
<tr>
<td>debugLevel</td>
<td>打印日志级别默认warn</td>
<td>String</td>
<td>debug, warn</td>
</tr>
</tbody>
</table>
<h5>调用方法和事件回调</h5>
<table class="table table-bordered">
<thead class="thead-light">
<tr>
<th>方法/事件</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>play</td>
<td>播放</td>
</tr>
<tr>
<td>playback</td>
<td>播放录像</td>
</tr>
<tr>
<td>pause</td>
<td>暂停播放</td>
</tr>
<tr>
<td>isPause</td>
<td>返回是否暂停中状态</td>
</tr>
<tr>
<td>setBufferTime</td>
<td>设置最大缓冲时长</td>
</tr>
<tr>
<td>setVolume</td>
<td>设置音量</td>
</tr>
<tr>
<td>getVolume</td>
<td>获取音量</td>
</tr>
<tr>
<td>exitFullscreen</td>
<td>退出全屏(取消全屏)播放视频</td>
</tr>
<tr>
<td>mute</td>
<td>静音</td>
</tr>
<tr>
<td>cancelMute</td>
<td>取消静音</td>
</tr>
<tr>
<td>isMute</td>
<td>返回是否静音</td>
</tr>
<tr>
<td>screenshot</td>
<td>获取快照</td>
</tr>
<tr>
<td>setFullscreen</td>
<td>全屏</td>
</tr>
<tr>
<td>setStreamQuality</td>
<td>设置分辨率必须是qualityConfig里面的数据</td>
</tr>
<tr>
<td>forward</td>
<td>设置录像倍数</td>
</tr>
<tr>
<td>setPlaybackStartTime</td>
<td>设置录像跳转时间/s</td>
</tr>
<tr>
<td>getVideoInfo</td>
<td>获取视频信息</td>
</tr>
<tr>
<td>getAudioInfo</td>
<td>获取音频信息</td>
</tr>
<tr>
<td>destroy</td>
<td>关闭视频,释放底层资源</td>
</tr>
<tr>
<td>play</td>
<td>播放事件</td>
</tr>
<tr>
<td>pause</td>
<td>暂停事件</td>
</tr>
<tr>
<td>videoInfo</td>
<td>视频信息</td>
</tr>
<tr>
<td>audioInfo</td>
<td>音频信息</td>
</tr>
<tr>
<td>mute</td>
<td>音频事件</td>
</tr>
<tr>
<td>error</td>
<td>播放异常</td>
</tr>
<tr>
<td>kBps</td>
<td>当前网速单位KB 每秒1次</td>
</tr>
<tr>
<td>recordEnd</td>
<td>录制结束的事件</td>
</tr>
<tr>
<td>recordStart</td>
<td>录制开始的事件</td>
</tr>
<tr>
<td>fullscreen</td>
<td>当前是否全屏</td>
</tr>
<tr>
<td>streamQualityChange</td>
<td>清晰度回调</td>
</tr>
<tr>
<td>playbackSeek</td>
<td>录像时间轴跳转回调</td>
</tr>
<tr>
<td>playbackPreRateChange</td>
<td>录像倍数的回调</td>
</tr>
<tr>
<td>currentPts</td>
<td>监听当前渲染帧的时间戳(流里面的)</td>
</tr>
</tbody>
</table>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"></script>
<script>
var easypro;
var $player = document.getElementById('play');
var $destroy = document.getElementById('destroy');
var $rePlay = document.getElementById('rePlay');
var $playHref = document.getElementById('playHref');
var $container = document.querySelector('#video');
var $videoBufferDelay = document.querySelector('#videoBufferDelay');
var $useMSE = document.querySelector('#useMSE');
var $useWCS = document.querySelector('#useWCS');
var $useSIMD = document.querySelector('#useSIMD');
var $hasAudio = document.querySelector('#hasAudio');
var $isNakedFlow = document.querySelector('#isNakedFlow');
var $websocket1006ErrorReplay = document.querySelector('#websocket1006ErrorReplay');
var $networkDelayTimeoutReplay = document.querySelector('#networkDelayTimeoutReplay');
var $heartTimeout = document.querySelector('#heartTimeout');
var $replayUseLastFrameShow = document.querySelector('#replayUseLastFrameShow');
var $fullscreenWatermarkConfig = document.querySelector('#fullscreenWatermarkConfig');
var $background = document.querySelector('#background');
function create(options) {
options = options || {}
easypro = new EasyPlayerPro({
container: $container,
videoBuffer: 0.2, // 缓存时长
videoBufferDelay: Number($videoBufferDelay.value), // 1000s
decoder: './js/decoder-pro.js',
isResize: false,
text: "",
loadingText: "加载中", debug: true,
debugLevel: "debug",
useMSE: $useMSE.checked === true,
useSIMD: $useSIMD.checked === true,
useWCS: $useWCS.checked === true,
hasAudio: $hasAudio.checked === true,
websocket1006ErrorReplay: $websocket1006ErrorReplay.checked === true,
networkDelayTimeoutReplay: $networkDelayTimeoutReplay.checked === true,
useMThreading: true,
showBandwidth: true, // 显示网速
showPerformance: true, // 显示性能
operateBtns: {
fullscreen: true,
screenshot: true,
play: true,
audio: true,
ptz: true,
quality: true,
performance: true,
screenshotFn: screenshotFn,
},
background: $background.value,
timeout: 10,
qualityConfig: ['普清', '高清', '超清', '4K', '8K'],
forceNoOffscreen: true,
isNotMute: false,
heartTimeout: Number($heartTimeout.value),
ptzClickType: 'mouseDownAndUp',
ptzZoomShow: true,
ptzMoreArrowShow: true,
ptzApertureShow: true,
ptzFocusShow: true,
pauseAndNextPlayUseLastFrameShow: $replayUseLastFrameShow.checked === true,
heartTimeoutReplayUseLastFrameShow: $replayUseLastFrameShow.checked === true,
replayUseLastFrameShow: $replayUseLastFrameShow.checked === true, // 重播使用上一帧显示
fullscreenWatermarkConfig: {
text: $fullscreenWatermarkConfig.value,
}
});
}
const screenshotFn = () => {
if (easypro) {
easypro.screenshotWatermark({
text: {
content: `${$fullscreenWatermarkConfig.value}`,
fontSize: '46',
color: 'rgba(100,100,100,.6)',
},
opacity: 0.8,
right: 20,
top: 50,
});
}
};
create();
easypro.on('streamQualityChange', (value) => {
console.log('streamQualityChange', value);
})
easypro.on('timeUpdate', (value) => {
// console.log('timeUpdate', value);
})
easypro.on('stats', (stats) => {
// console.log('stats', stats);
})
easypro.on('error', (errorType, message) => {
console.error('error', errorType, message);
})
easypro.on('crashLog', (info) => {
console.error('crashLog', info);
})
easypro.on('playFailedAndPaused', (reason, lastFrameInfo, msg) => {
console.error('playFailedAndPaused', reason, lastFrameInfo, msg);
});
function play() {
var href = $playHref.value;
if (href) {
easypro.play(href);
} else {
easypro.showErrorMessageTips('播放地址不能为空');
}
}
function replay(options) {
if (easypro) {
easypro.destroy().then(() => {
create(options);
play();
});
} else {
create();
play();
}
}
$player.addEventListener('click', function () {
play();
}, false)
$destroy.addEventListener('click', function () {
if (easypro) {
easypro.destroy().then(() => {
create();
});
} else {
create();
}
})
$useMSE.addEventListener('change', function () {
replay();
})
$useSIMD.addEventListener('change', function () {
replay();
})
$useWCS.addEventListener('change', function () {
replay();
})
$hasAudio.addEventListener('change', function () {
replay();
})
$websocket1006ErrorReplay.addEventListener('change', function () {
replay();
})
$rePlay.addEventListener('click', function () {
replay();
})
$background.addEventListener('change', function () {
if (easypro) {
easypro.destroy().then(() => {
create();
});
} else {
create();
}
})
$networkDelayTimeoutReplay.addEventListener('change', function () {
replay();
})
</script>
</body>
</html>