mirror of
https://github.com/bytedance/xgplayer.git
synced 2025-04-05 03:05:02 +08:00
refactor: 💡 add fixtures
This commit is contained in:
parent
26931f06ec
commit
8909a5e81e
1
.gitignore
vendored
1
.gitignore
vendored
@ -85,6 +85,7 @@ packages/*/types/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
fixtures/*/*
|
fixtures/*/*
|
||||||
!fixtures/*/index.html
|
!fixtures/*/index.html
|
||||||
|
!fixtures/*/index.js
|
||||||
|
|
||||||
#http-server cert
|
#http-server cert
|
||||||
*.pem
|
*.pem
|
||||||
|
322
fixtures/flv/index.js
Normal file
322
fixtures/flv/index.js
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
import Player from '../../packages/xgplayer/src'
|
||||||
|
import FlvPlayer from '../../packages/xgplayer-flv/src'
|
||||||
|
|
||||||
|
localStorage.setItem('xgd', 1)
|
||||||
|
function defaultOpt() {
|
||||||
|
return {
|
||||||
|
isLive: true,
|
||||||
|
autoplay: false,
|
||||||
|
autoplayMuted: false,
|
||||||
|
retryTimes: 3,
|
||||||
|
retryCount: 3,
|
||||||
|
retryDelay: 1000,
|
||||||
|
analyzeDuration: 5000,
|
||||||
|
loadTimeout: 10000,
|
||||||
|
bufferBehind: 10,
|
||||||
|
maxJumpDistance: 3,
|
||||||
|
maxReaderInterval: 5000,
|
||||||
|
seamlesslyReload: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var cachedOpt = localStorage.getItem('xg:test:flv:opt')
|
||||||
|
try { cachedOpt = JSON.parse(cachedOpt) } catch (error) { cachedOpt = undefined }
|
||||||
|
var opts = Object.assign({
|
||||||
|
// url: 'https://1011.hlsplay.aodianyun.com/demo/game.flv',
|
||||||
|
url: 'https://pull-flv-l1.douyincdn.com/stage/stream-399911386870710302_ld.flv?keeptime=00093a80&wsSecret=84c8c84e064fb6c6aaad6ec54c5c8247&wsTime=63315a10&abr_pts=1950715',
|
||||||
|
}, defaultOpt(), cachedOpt)
|
||||||
|
var testPoint = Number(localStorage.getItem('xg:test:flv:point'))
|
||||||
|
|
||||||
|
if (isNaN(testPoint)) testPoint = 0
|
||||||
|
|
||||||
|
window.onload = function () {
|
||||||
|
var dTestPoint = document.getElementById('test-point')
|
||||||
|
var dTestPointDesc = document.getElementById('test-point-desc')
|
||||||
|
|
||||||
|
var doPresetUrl = document.getElementById('preset-url')
|
||||||
|
var doUrl = document.getElementById('url')
|
||||||
|
var doAutoplay = document.getElementById('autoplay')
|
||||||
|
var doAutoplayMuted = document.getElementById('autoplay-muted')
|
||||||
|
var doSeamlesslyReload = document.getElementById('seamlessly-reload')
|
||||||
|
var doLoadTimeout = document.getElementById('load-timeout')
|
||||||
|
var doRetryCount = document.getElementById('retry-count')
|
||||||
|
var doRetryDelay = document.getElementById('retry-delay')
|
||||||
|
var doAnalyzeDuration = document.getElementById('analyze-duration')
|
||||||
|
var doFetchOptions = document.getElementById('fetch-options')
|
||||||
|
var doBufferBehind = document.getElementById('buffer-behind')
|
||||||
|
var doMaxJumpDistance = document.getElementById('max-jump-distance')
|
||||||
|
var doMaxReaderInterval = document.getElementById('max-reader-interval')
|
||||||
|
var doTargetLatency = document.getElementById('target-latency')
|
||||||
|
var doMaxLatency = document.getElementById('max-latency')
|
||||||
|
var doDisconnectTime = document.getElementById('disconnect-time')
|
||||||
|
|
||||||
|
var dbResetOpt = document.getElementById('reset-opt')
|
||||||
|
var dbApplyOpt = document.getElementById('apply-opt')
|
||||||
|
var dbPlay = document.getElementById('play')
|
||||||
|
var dbPause = document.getElementById('pause')
|
||||||
|
var dbReplay = document.getElementById('replay')
|
||||||
|
var dbDestroy = document.getElementById('destroy')
|
||||||
|
var dbSwitchUrl = document.getElementById('switch-url')
|
||||||
|
var dbSetUrl = document.getElementById('set-url')
|
||||||
|
var dbSeek = document.getElementById('seek')
|
||||||
|
|
||||||
|
var dlEvent = document.getElementById('event')
|
||||||
|
var dlError = document.getElementById('error')
|
||||||
|
var dlLogPause = document.getElementById('log-pause')
|
||||||
|
|
||||||
|
var dsSpeed = document.getElementById('speed')
|
||||||
|
var dsFrame = document.getElementById('frame')
|
||||||
|
var dsBuffer = document.getElementById('buffer')
|
||||||
|
var dsOption = document.getElementById('option')
|
||||||
|
|
||||||
|
dTestPoint.selectedIndex = testPoint
|
||||||
|
dsOption.innerHTML = '<pre>' + JSON.stringify(opts, null, 2) + '</pre>'
|
||||||
|
|
||||||
|
function inp(d) { return d.getElementsByTagName('input')[0] }
|
||||||
|
|
||||||
|
var player
|
||||||
|
|
||||||
|
function updateOpts(key, value, type) {
|
||||||
|
if (type === 'object') {
|
||||||
|
try {
|
||||||
|
value = (new Function('x', 'return ' + value))()
|
||||||
|
} catch (error) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type === 'number') {
|
||||||
|
opts[key] = Number(value)
|
||||||
|
}else{
|
||||||
|
opts[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
localStorage.setItem('xg:test:flv:opt', JSON.stringify(opts))
|
||||||
|
dsOption.innerHTML = '<pre>' + JSON.stringify(opts, null, 2) + '</pre>'
|
||||||
|
}
|
||||||
|
function resetOpts() {
|
||||||
|
opts = Object.assign({ url: opts.url }, defaultOpt())
|
||||||
|
localStorage.setItem('xg:test:flv:opt', JSON.stringify(opts))
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
function initPlayer() {
|
||||||
|
if (player) {
|
||||||
|
player.destroy()
|
||||||
|
setTimeout(init, 100)
|
||||||
|
} else {
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
function init() {
|
||||||
|
window.player = player = new Player({
|
||||||
|
el: document.getElementById('player'),
|
||||||
|
plugins: [FlvPlayer],
|
||||||
|
url: opts.url,
|
||||||
|
isLive: opts.isLive,
|
||||||
|
autoplay: opts.autoplay,
|
||||||
|
autoplayMuted: opts.autoplayMuted,
|
||||||
|
flv: opts
|
||||||
|
});
|
||||||
|
dlEvent.innerHTML = ''
|
||||||
|
dlError.innerHTML = ''
|
||||||
|
|
||||||
|
function pushEvent(name, value, container) {
|
||||||
|
container = container || dlEvent
|
||||||
|
if (container === dlEvent && dlLogPause.checked) return
|
||||||
|
console.debug('[test]', name, value)
|
||||||
|
if (container === dlEvent && logFilter && !logFilter(name, value)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
value = JSON.stringify(value)
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
|
var record = document.createElement('div')
|
||||||
|
record.innerHTML = '<div class="mb-2"><span class="text-base pr-2 bg-green-500 text-white">' + name + ' / ' + player.video.currentTime + '</span>' + value + '</div>'
|
||||||
|
container.prepend(record)
|
||||||
|
}
|
||||||
|
|
||||||
|
player.on('loadstart', function (event) { pushEvent('loadstart', event) })
|
||||||
|
player.on('loadeddata', function (event) { pushEvent('loadeddata', event) })
|
||||||
|
player.on('play', function (event) { pushEvent('play', event) })
|
||||||
|
player.on('pause', function (event) { pushEvent('pause', event) })
|
||||||
|
player.on('ended', function (event) { pushEvent('ended', event) })
|
||||||
|
player.on('autoplay_was_prevented', function (event) { pushEvent('autoplay_was_prevented', event) })
|
||||||
|
player.on('playing', function (event) { pushEvent('playing', event) })
|
||||||
|
player.on('seeking', function (event) { pushEvent('seeking', event) })
|
||||||
|
player.on('seeked', function (event) { pushEvent('seeked', event) })
|
||||||
|
player.on('waiting', function (event) { pushEvent('waiting', event) })
|
||||||
|
player.on('canplay', function (event) { pushEvent('canplay', event) })
|
||||||
|
player.on('durationchange', function (event) { pushEvent('durationchange', event) })
|
||||||
|
player.on('ready', function (event) { pushEvent('ready', event) })
|
||||||
|
player.on('complete', function (event) { pushEvent('complete', event) })
|
||||||
|
player.on('urlchange', function (event) { pushEvent('urlchange', event) })
|
||||||
|
player.on('destroy', function (event) { pushEvent('destroy', event) })
|
||||||
|
player.on('replay', function (event) { pushEvent('replay', event) })
|
||||||
|
player.on('retry', function (event) { pushEvent('retry', event) })
|
||||||
|
player.on('core_event', function (event) { pushEvent(event.eventName, event) })
|
||||||
|
player.on('error', function (event) { pushEvent(event.errorType, event, dlError) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlight (d) {d.classList.add('bg-yellow-300')}
|
||||||
|
function show(d, h) { d.style.display = 'block'; if (h) highlight(d) }
|
||||||
|
|
||||||
|
var logFilter
|
||||||
|
var desc = ''
|
||||||
|
switch (testPoint) {
|
||||||
|
case 0: {
|
||||||
|
show(doAutoplay)
|
||||||
|
show(doAutoplayMuted)
|
||||||
|
show(doSeamlesslyReload)
|
||||||
|
show(doLoadTimeout)
|
||||||
|
show(doRetryCount)
|
||||||
|
show(doRetryDelay)
|
||||||
|
show(doAnalyzeDuration)
|
||||||
|
show(doFetchOptions)
|
||||||
|
show(doBufferBehind)
|
||||||
|
show(doMaxJumpDistance)
|
||||||
|
show(doTargetLatency)
|
||||||
|
show(doMaxLatency)
|
||||||
|
show(doDisconnectTime)
|
||||||
|
show(doMaxReaderInterval)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: {
|
||||||
|
desc = '设置高亮四个参数。<br>查看"开发者工具"的Network面板是否进行相应次数的重试<br>查看“日志”是否触发相应次数的重试事件“core.loadretry”、请求开始“core.loadstart”和请求完成“core.loadcomplete”'
|
||||||
|
desc += '<br>拉流最大探测时间: 对于存在音、视频标识,但是一直拉取不到音、视频数据的case, 拉流数据超过设置的时长后当做无音频或者无视频起播'
|
||||||
|
show(doLoadTimeout, true)
|
||||||
|
show(doRetryCount, true)
|
||||||
|
show(doRetryDelay, true)
|
||||||
|
show(doAnalyzeDuration, true)
|
||||||
|
highlight(dlEvent)
|
||||||
|
logFilter = function (name) {
|
||||||
|
return name === 'core.loadretry' || name === 'core.loadcomplete' || name === 'core.loadstart'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: {
|
||||||
|
desc = '设置高亮参数,并观察状态区域中的“当前时间之前缓存时长”是否与设置的值差不多(允许一定的误差)'
|
||||||
|
show(doBufferBehind, true)
|
||||||
|
highlight(dsBuffer)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: {
|
||||||
|
desc = '设置高亮两个参数,观察视频是否自动播放(自动播放失败,点击播放按钮可以正常播放),如果是静音自动播放则必须自动播放成功'
|
||||||
|
show(doAutoplay, true)
|
||||||
|
show(doAutoplayMuted, true)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: {
|
||||||
|
desc = '点击 API 方法中的 “切换url” 和 “设置url” 按钮,观察是否切换视频成功,并且可以播放,暂停'
|
||||||
|
dbSwitchUrl.style.background="rgb(245, 158, 11)"
|
||||||
|
dbSetUrl.style.background="rgb(245, 158, 11)"
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5: {
|
||||||
|
desc = '设置该参数,然后在直播中暂停,等待设置该参数差不多的时间,然后点播放按钮,观察直播是否拉流(出现黑屏)。等待小于该时间点播放可以连续播放不会重新拉流(不黑屏)' +
|
||||||
|
'<br> 如果设置了无缝重拉流则不会黑屏'
|
||||||
|
show(doDisconnectTime, true)
|
||||||
|
show(doSeamlesslyReload, true)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dTestPointDesc.innerHTML = desc
|
||||||
|
|
||||||
|
inp(doUrl).value = opts.url
|
||||||
|
inp(doAutoplay).checked = opts.autoplay
|
||||||
|
inp(doAutoplayMuted).checked = opts.autoplayMuted
|
||||||
|
inp(doSeamlesslyReload).checked = opts.seamlesslyReload
|
||||||
|
inp(doLoadTimeout).value = opts.loadTimeout
|
||||||
|
inp(doRetryCount).value = opts.retryCount
|
||||||
|
inp(doRetryDelay).value = opts.retryDelay
|
||||||
|
inp(doAnalyzeDuration).value = opts.analyzeDuration
|
||||||
|
inp(doFetchOptions).value = opts.fetchOptions || ''
|
||||||
|
inp(doBufferBehind).value = opts.bufferBehind
|
||||||
|
inp(doMaxJumpDistance).value = opts.maxJumpDistance
|
||||||
|
inp(doTargetLatency).value = opts.targetLatency
|
||||||
|
inp(doMaxLatency).value = opts.maxLatency
|
||||||
|
inp(doDisconnectTime).value = opts.disconnectTime
|
||||||
|
inp(doMaxReaderInterval).value = opts.maxReaderInterval
|
||||||
|
|
||||||
|
inp(doUrl).onchange = function () { updateOpts('url', this.value, 'string') }
|
||||||
|
inp(doAutoplay).onchange = function () { updateOpts('autoplay', this.checked) }
|
||||||
|
inp(doAutoplayMuted).onchange = function () { updateOpts('autoplayMuted', this.checked) }
|
||||||
|
inp(doSeamlesslyReload).onchange = function () { updateOpts('seamlesslyReload', this.checked) }
|
||||||
|
inp(doLoadTimeout).onchange = function () { updateOpts('loadTimeout', this.value, 'number') }
|
||||||
|
inp(doRetryCount).onchange = function () { updateOpts('retryCount', this.value, 'number') }
|
||||||
|
inp(doRetryDelay).onchange = function () { updateOpts('retryDelay', this.value, 'number') }
|
||||||
|
inp(doAnalyzeDuration).onchange = function () { updateOpts('analyzeDuration', this.value, 'number') }
|
||||||
|
inp(doFetchOptions).onchange = function () { updateOpts('fetchOptions', this.value, 'object') }
|
||||||
|
inp(doBufferBehind).onchange = function () { updateOpts('bufferBehind', this.value, 'number') }
|
||||||
|
inp(doMaxJumpDistance).onchange = function () { updateOpts('maxJumpDistance', this.value, 'number') }
|
||||||
|
inp(doTargetLatency).onchange = function () { updateOpts('targetLatency', this.value, 'number') }
|
||||||
|
inp(doMaxLatency).onchange = function () { updateOpts('maxLatency', this.value, 'number') }
|
||||||
|
inp(doDisconnectTime).onchange = function () { updateOpts('disconnectTime', this.value, 'number') }
|
||||||
|
inp(doMaxReaderInterval).onchange = function () { updateOpts('maxReaderInterval', this.value, 'number') }
|
||||||
|
|
||||||
|
initPlayer()
|
||||||
|
|
||||||
|
dbResetOpt.onclick = resetOpts
|
||||||
|
dbApplyOpt.onclick = initPlayer
|
||||||
|
dbPlay.onclick = function () { player.play() }
|
||||||
|
dbPause.onclick = function () { player.pause() }
|
||||||
|
dbReplay.onclick = function () { player.replay() }
|
||||||
|
dbDestroy.onclick = function () { player.destroy() }
|
||||||
|
dbSwitchUrl.onclick = function () {
|
||||||
|
var url = window.prompt('设置的 url 地址')
|
||||||
|
if (!url) return
|
||||||
|
var seamless = window.prompt('是否无缝切换 “true” 或 “false”', false)
|
||||||
|
player.switchURL(url, seamless.trim() === 'true')
|
||||||
|
}
|
||||||
|
dbSetUrl.onclick = function () {
|
||||||
|
var url = window.prompt('设置的 url 地址')
|
||||||
|
if (url) player.src = url
|
||||||
|
}
|
||||||
|
dbSeek.onclick = function () {
|
||||||
|
var time = window.prompt('设置的跳转到的事件点')
|
||||||
|
if (time == null) return
|
||||||
|
time = Number(time)
|
||||||
|
if (isNaN(time)) return
|
||||||
|
player.seek(time)
|
||||||
|
}
|
||||||
|
|
||||||
|
dTestPoint.onchange = function () {
|
||||||
|
localStorage.setItem('xg:test:flv:point', this.value)
|
||||||
|
resetOpts()
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
var lastPlayback = null
|
||||||
|
var fps = 0
|
||||||
|
var prevTime = 0
|
||||||
|
setInterval(function () {
|
||||||
|
if (player && player.plugins.flv) {
|
||||||
|
var t = player.currentTime
|
||||||
|
prevTime = t
|
||||||
|
var flv = player.plugins.flv.core
|
||||||
|
var buf = flv.bufferInfo()
|
||||||
|
var pq = flv.playbackQuality()
|
||||||
|
var sp = flv.speedInfo()
|
||||||
|
if (lastPlayback) {
|
||||||
|
fps = Math.round((pq.totalVideoFrames - lastPlayback.totalVideoFrames) / (pq.creationTime - lastPlayback.creationTime) * 1000)
|
||||||
|
}
|
||||||
|
lastPlayback = pq
|
||||||
|
|
||||||
|
dsBuffer.innerHTML =
|
||||||
|
'<p>当前时间:' + t + 's</p>' +
|
||||||
|
'<p>剩余缓存时长:' + buf.remaining + 's</p>' +
|
||||||
|
'<p>当前时间之前缓存时长:' + buf.behind + 's</p>' +
|
||||||
|
'<p>总缓存时长:' + buf.length + 's</p>' +
|
||||||
|
'<p>buffers:' + JSON.stringify(buf.buffers) + '</p>'
|
||||||
|
|
||||||
|
dsFrame.innerHTML =
|
||||||
|
'<p>总渲染帧数:' + pq.totalVideoFrames + '</p>' +
|
||||||
|
'<p>掉帧数量:' + pq.droppedVideoFrames + '</p>' +
|
||||||
|
'<p>fps:' + fps + '</p>'
|
||||||
|
|
||||||
|
dsSpeed.innerHTML =
|
||||||
|
'<p>当前速度:' + Math.round(sp.speed / (8 * 1024)) + 'KB/s</p>' +
|
||||||
|
'<p>平均速度:' + Math.round(sp.avgSpeed / (8 * 1024)) + 'KB/s</p>'
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
}
|
398
fixtures/hls/index.js
Normal file
398
fixtures/hls/index.js
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
import Player from '../../packages/xgplayer/src'
|
||||||
|
import HlsPlayer from '../../packages/xgplayer-hls/src'
|
||||||
|
|
||||||
|
localStorage.setItem('xgd', 1)
|
||||||
|
function defaultOpt() {
|
||||||
|
return {
|
||||||
|
isLive: false,
|
||||||
|
autoplay: false,
|
||||||
|
autoplayMuted: false,
|
||||||
|
retryTimes: 3,
|
||||||
|
retryCount: 3,
|
||||||
|
retryDelay: 1000,
|
||||||
|
loadTimeout: 10000,
|
||||||
|
preloadTime: 10,
|
||||||
|
bufferBehind: 10,
|
||||||
|
maxJumpDistance: 3,
|
||||||
|
startTime: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var cachedOpt = localStorage.getItem('xg:test:hls:opt')
|
||||||
|
try { cachedOpt = JSON.parse(cachedOpt) } catch (error) { cachedOpt = undefined }
|
||||||
|
var opts = Object.assign({
|
||||||
|
url: 'https://test-streams.mux.dev/x36xhzz/url_0/193039199_mp4_h264_aac_hd_7.m3u8',
|
||||||
|
}, defaultOpt(), cachedOpt)
|
||||||
|
var testPoint = Number(localStorage.getItem('xg:test:hls:point'))
|
||||||
|
if (isNaN(testPoint)) testPoint = 0
|
||||||
|
|
||||||
|
window.onload = function () {
|
||||||
|
var dTestPoint = document.getElementById('test-point')
|
||||||
|
var dTestPointDesc = document.getElementById('test-point-desc')
|
||||||
|
|
||||||
|
var doPresetUrl = document.getElementById('preset-url')
|
||||||
|
var doUrl = document.getElementById('url')
|
||||||
|
var doIsLive = document.getElementById('is-live')
|
||||||
|
var doAutoplay = document.getElementById('autoplay')
|
||||||
|
var doAutoplayMuted = document.getElementById('autoplay-muted')
|
||||||
|
var doLoadTimeout = document.getElementById('load-timeout')
|
||||||
|
var doRetryCount = document.getElementById('retry-count')
|
||||||
|
var doRetryDelay = document.getElementById('retry-delay')
|
||||||
|
var doFetchOptions = document.getElementById('fetch-options')
|
||||||
|
var doPreloadTime = document.getElementById('preload-time')
|
||||||
|
var doBufferBehind = document.getElementById('buffer-behind')
|
||||||
|
var doMaxJumpDistance = document.getElementById('max-jump-distance')
|
||||||
|
var doStartTime = document.getElementById('start-time')
|
||||||
|
var doTargetLatency = document.getElementById('target-latency')
|
||||||
|
var doMaxLatency = document.getElementById('max-latency')
|
||||||
|
var doDisconnectTime = document.getElementById('disconnect-time')
|
||||||
|
|
||||||
|
var dbResetOpt = document.getElementById('reset-opt')
|
||||||
|
var dbApplyOpt = document.getElementById('apply-opt')
|
||||||
|
var dbPlay = document.getElementById('play')
|
||||||
|
var dbPause = document.getElementById('pause')
|
||||||
|
var dbReplay = document.getElementById('replay')
|
||||||
|
var dbDestroy = document.getElementById('destroy')
|
||||||
|
var dbSwitchUrl = document.getElementById('switch-url')
|
||||||
|
var dbSetUrl = document.getElementById('set-url')
|
||||||
|
var dbSeek = document.getElementById('seek')
|
||||||
|
|
||||||
|
var dStreamsContainer = document.getElementById('streams')
|
||||||
|
var dStreamForce = document.getElementById('stream-force')
|
||||||
|
var dVideoStreams = document.getElementById('video-streams')
|
||||||
|
var dAudioStreams = document.getElementById('audio-streams')
|
||||||
|
|
||||||
|
var dlEvent = document.getElementById('event')
|
||||||
|
var dlError = document.getElementById('error')
|
||||||
|
|
||||||
|
var dsSpeed = document.getElementById('speed')
|
||||||
|
var dsFrame = document.getElementById('frame')
|
||||||
|
var dsBuffer = document.getElementById('buffer')
|
||||||
|
var dsOption = document.getElementById('option')
|
||||||
|
|
||||||
|
dTestPoint.selectedIndex = testPoint
|
||||||
|
dsOption.innerHTML = '<pre>' + JSON.stringify(opts, null, 2) + '</pre>'
|
||||||
|
|
||||||
|
function inp(d) { return d.getElementsByTagName('input')[0] }
|
||||||
|
|
||||||
|
var player
|
||||||
|
|
||||||
|
function updateOpts(key, value, type) {
|
||||||
|
if (type === 'object') {
|
||||||
|
try {
|
||||||
|
value = (new Function('x', 'return ' + value))()
|
||||||
|
} catch (error) { }
|
||||||
|
}
|
||||||
|
opts[key] = value
|
||||||
|
localStorage.setItem('xg:test:hls:opt', JSON.stringify(opts))
|
||||||
|
dsOption.innerHTML = '<pre>' + JSON.stringify(opts, null, 2) + '</pre>'
|
||||||
|
}
|
||||||
|
function resetOpts() {
|
||||||
|
opts = Object.assign({ url: opts.url }, defaultOpt())
|
||||||
|
localStorage.setItem('xg:test:hls:opt', JSON.stringify(opts))
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
function initPlayer() {
|
||||||
|
if (player) {
|
||||||
|
player.destroy()
|
||||||
|
setTimeout(init, 100)
|
||||||
|
} else {
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
function init() {
|
||||||
|
window.player = player = new Player({
|
||||||
|
// mediaType: 'live-video',
|
||||||
|
el: document.getElementById('player'),
|
||||||
|
plugins: [HlsPlayer],
|
||||||
|
url: opts.url,
|
||||||
|
isLive: opts.isLive,
|
||||||
|
startTime: opts.startTime,
|
||||||
|
autoplay: opts.autoplay,
|
||||||
|
autoplayMuted: opts.autoplayMuted,
|
||||||
|
hls: Object.assign({}, opts, {
|
||||||
|
fetchOptions: Object.assign({
|
||||||
|
referrer: 'no-referrer',
|
||||||
|
referrerPolicy: 'no-referrer'
|
||||||
|
}, opts.fetchOptions)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
dlEvent.innerHTML = ''
|
||||||
|
dlError.innerHTML = ''
|
||||||
|
|
||||||
|
function pushEvent(name, value, container) {
|
||||||
|
container = container || dlEvent
|
||||||
|
console.debug('[test]', name, value)
|
||||||
|
if (container === dlEvent && logFilter && !logFilter(name, value)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'core.metadataparsed') {
|
||||||
|
if (value.track?.samples?.length > 100) {
|
||||||
|
return { '_': '数据过大,请查看devtools' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
value = JSON.stringify(value)
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
|
var record = document.createElement('div')
|
||||||
|
record.innerHTML = '<div class="mb-2"><span class="text-base pr-2 bg-green-500 text-white">' + name + ' / ' + player.video.currentTime + '</span>' + value + '</div>'
|
||||||
|
container.prepend(record)
|
||||||
|
}
|
||||||
|
|
||||||
|
player.on('loadstart', function (event) { pushEvent('loadstart', event) })
|
||||||
|
player.on('loadeddata', function (event) { pushEvent('loadeddata', event) })
|
||||||
|
player.on('play', function (event) { pushEvent('play', event) })
|
||||||
|
player.on('pause', function (event) { pushEvent('pause', event) })
|
||||||
|
player.on('ended', function (event) { pushEvent('ended', event) })
|
||||||
|
player.on('autoplay_was_prevented', function (event) { pushEvent('autoplay_was_prevented', event) })
|
||||||
|
player.on('playing', function (event) { pushEvent('playing', event) })
|
||||||
|
player.on('seeking', function (event) { pushEvent('seeking', event) })
|
||||||
|
player.on('seeked', function (event) { pushEvent('seeked', event) })
|
||||||
|
player.on('waiting', function (event) { pushEvent('waiting', event) })
|
||||||
|
player.on('canplay', function (event) { pushEvent('canplay', event) })
|
||||||
|
player.on('durationchange', function (event) { pushEvent('durationchange', event) })
|
||||||
|
player.on('ready', function (event) { pushEvent('ready', event) })
|
||||||
|
player.on('complete', function (event) { pushEvent('complete', event) })
|
||||||
|
player.on('urlchange', function (event) { pushEvent('urlchange', event) })
|
||||||
|
player.on('destroy', function (event) { pushEvent('destroy', event) })
|
||||||
|
player.on('replay', function (event) { pushEvent('replay', event) })
|
||||||
|
player.on('retry', function (event) { pushEvent('retry', event) })
|
||||||
|
player.on('core_event', function (event) { pushEvent(event.eventName, event) })
|
||||||
|
player.on('error', function (event) { pushEvent(event.errorType, event, dlError) })
|
||||||
|
|
||||||
|
dStreamForce.checked = true
|
||||||
|
function refreshStreams() {
|
||||||
|
var hls = player.plugins.hls.core
|
||||||
|
var streams = hls.streams
|
||||||
|
var currentStream = hls.currentStream
|
||||||
|
var streams = hls.streams
|
||||||
|
dStreamsContainer.style.display = 'none'
|
||||||
|
dVideoStreams.innerHTML = ''
|
||||||
|
dAudioStreams.innerHTML = ''
|
||||||
|
if (streams.length > 2) {
|
||||||
|
dStreamsContainer.style.display = 'block'
|
||||||
|
streams.forEach(s => {
|
||||||
|
var texts = []
|
||||||
|
if (s.width && s.height) texts.push(s.width + 'x' + s.height)
|
||||||
|
if (s.videoCodec) texts.push(s.videoCodec.split('.')[0])
|
||||||
|
if (s.bitrate) texts.push(Math.round(s.bitrate / 8192) + 'KBs')
|
||||||
|
var button = document.createElement('button')
|
||||||
|
button.setAttribute('class', 'py-1 px-2 mt-1 text-white shadow-md mr-2 ' + (currentStream.id === s.id ? 'bg-red-500' : 'bg-green-500'))
|
||||||
|
button.textContent = texts.join('/')
|
||||||
|
button.onclick = function () {
|
||||||
|
hls.switchStream(s.id, dStreamForce.checked).then(function (s) {
|
||||||
|
if (s && s.segments.length && !hls.isLive) {
|
||||||
|
refreshStreams()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
dVideoStreams.appendChild(button)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (currentStream.audioStreams.length > 2) {
|
||||||
|
dStreamsContainer.style.display = 'block'
|
||||||
|
var currentAudio = currentStream.currentAudioStream
|
||||||
|
currentStream.audioStreams.forEach(s => {
|
||||||
|
var texts = []
|
||||||
|
if (s.name) texts.push(s.name)
|
||||||
|
if (s.lang) texts.push(s.lang)
|
||||||
|
if (s.channels) texts.push(s.channels)
|
||||||
|
var button = document.createElement('button')
|
||||||
|
button.setAttribute('class', 'py-1 px-2 mt-1 text-white shadow-md mr-2 ' + (currentAudio.id === s.id ? 'bg-red-500' : 'bg-green-500'))
|
||||||
|
button.textContent = texts.join('/')
|
||||||
|
button.onclick = function () {
|
||||||
|
hls.switchAudioStream(s.id, dStreamForce.checked).then(function (s) {
|
||||||
|
if (s && s.segments.length && !hls.isLive) {
|
||||||
|
refreshStreams()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
dAudioStreams.appendChild(button)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.on('core_event', function (event) {
|
||||||
|
if (event.eventName === HlsPlayer.EVENT.STREAM_PARSED) {
|
||||||
|
refreshStreams()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlight(d) { d.classList.add('bg-yellow-300') }
|
||||||
|
function show(d, h) { d.style.display = 'block'; if (h) highlight(d) }
|
||||||
|
|
||||||
|
var logFilter
|
||||||
|
var desc = ''
|
||||||
|
switch (testPoint) {
|
||||||
|
case 0: {
|
||||||
|
show(doAutoplay)
|
||||||
|
show(doAutoplayMuted)
|
||||||
|
show(doLoadTimeout)
|
||||||
|
show(doRetryCount)
|
||||||
|
show(doRetryDelay)
|
||||||
|
show(doFetchOptions)
|
||||||
|
show(doPreloadTime)
|
||||||
|
show(doBufferBehind)
|
||||||
|
show(doMaxJumpDistance)
|
||||||
|
show(doStartTime)
|
||||||
|
show(doTargetLatency)
|
||||||
|
show(doMaxLatency)
|
||||||
|
show(doDisconnectTime)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: {
|
||||||
|
desc = '设置高亮三个参数。<br>查看"开发者工具"的Network面板是否进行相应次数的重试<br>查看“日志”是否触发相应次数的重试事件“core.loadretry”、请求开始“core.loadstart”和请求完成“core.loadcomplete”'
|
||||||
|
show(doLoadTimeout, true)
|
||||||
|
show(doRetryCount, true)
|
||||||
|
show(doRetryDelay, true)
|
||||||
|
highlight(dlEvent)
|
||||||
|
logFilter = function (name) {
|
||||||
|
return name === 'core.loadretry' || name === 'core.loadcomplete' || name === 'core.loadstart'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: {
|
||||||
|
desc = '设置高亮两个参数,并观察状态区域中的“剩余缓存时长”和“当前时间之前缓存时长”是否与设置的值差不多(允许一定的误差)'
|
||||||
|
show(doPreloadTime, true)
|
||||||
|
show(doBufferBehind, true)
|
||||||
|
highlight(dsBuffer)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: {
|
||||||
|
desc = '设置高亮两个参数,观察视频是否自动播放(自动播放失败,点击播放按钮可以正常播放),如果是静音自动播放则必须自动播放成功'
|
||||||
|
show(doAutoplay, true)
|
||||||
|
show(doAutoplayMuted, true)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: {
|
||||||
|
desc = '点击 API 方法中的 “切换url” 和 “设置url” 按钮,观察是否切换视频成功,并且可以播放,暂停'
|
||||||
|
dbSwitchUrl.style.background = "rgb(245, 158, 11)"
|
||||||
|
dbSetUrl.style.background = "rgb(245, 158, 11)"
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5: {
|
||||||
|
desc = '设置点播的开始时间参数,查看视频是否在该时间点播放。点击 “seek” 按钮或拖动进度条,进行跳转播放时间,观察是否跳转成功。视频播放结束是否出现重播按钮,点击可以重播,点击重播按钮也可以重播。'
|
||||||
|
show(doStartTime, true)
|
||||||
|
dbReplay.style.background = "rgb(245, 158, 11)"
|
||||||
|
dbSeek.style.background = "rgb(245, 158, 11)"
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6: {
|
||||||
|
desc = '设置该参数,然后在直播中暂停,等待设置该参数差不多的时间,然后点播放按钮,观察直播是否拉流(出现黑屏)。等待小于该时间点播放可以连续播放不会重新拉流(不黑屏)'
|
||||||
|
show(doDisconnectTime, true)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dTestPointDesc.innerHTML = desc
|
||||||
|
|
||||||
|
inp(doUrl).value = opts.url
|
||||||
|
inp(doIsLive).checked = opts.isLive
|
||||||
|
inp(doAutoplay).checked = opts.autoplay
|
||||||
|
inp(doAutoplayMuted).checked = opts.autoplayMuted
|
||||||
|
inp(doLoadTimeout).value = opts.loadTimeout
|
||||||
|
inp(doRetryCount).value = opts.retryCount
|
||||||
|
inp(doRetryDelay).value = opts.retryDelay
|
||||||
|
inp(doFetchOptions).value = opts.fetchOptions || ''
|
||||||
|
inp(doPreloadTime).value = opts.preloadTime
|
||||||
|
inp(doBufferBehind).value = opts.bufferBehind
|
||||||
|
inp(doMaxJumpDistance).value = opts.maxJumpDistance
|
||||||
|
inp(doStartTime).value = opts.startTime
|
||||||
|
inp(doTargetLatency).value = opts.targetLatency
|
||||||
|
inp(doMaxLatency).value = opts.maxLatency
|
||||||
|
inp(doDisconnectTime).value = opts.disconnectTime
|
||||||
|
|
||||||
|
inp(doUrl).onchange = function () { updateOpts('url', this.value) }
|
||||||
|
inp(doIsLive).onchange = function () { updateOpts('isLive', this.checked) }
|
||||||
|
inp(doAutoplay).onchange = function () { updateOpts('autoplay', this.checked) }
|
||||||
|
inp(doAutoplayMuted).onchange = function () { updateOpts('autoplayMuted', this.checked) }
|
||||||
|
inp(doLoadTimeout).onchange = function () { updateOpts('loadTimeout', this.value) }
|
||||||
|
inp(doRetryCount).onchange = function () { updateOpts('retryCount', this.value) }
|
||||||
|
inp(doRetryDelay).onchange = function () { updateOpts('retryDelay', this.value) }
|
||||||
|
inp(doFetchOptions).onchange = function () { updateOpts('fetchOptions', this.value, 'object') }
|
||||||
|
inp(doPreloadTime).onchange = function () { updateOpts('preloadTime', this.value) }
|
||||||
|
inp(doBufferBehind).onchange = function () { updateOpts('bufferBehind', this.value) }
|
||||||
|
inp(doMaxJumpDistance).onchange = function () { updateOpts('maxJumpDistance', this.value) }
|
||||||
|
inp(doStartTime).onchange = function () { updateOpts('startTime', this.value) }
|
||||||
|
inp(doTargetLatency).onchange = function () { updateOpts('targetLatency', this.value) }
|
||||||
|
inp(doMaxLatency).onchange = function () { updateOpts('maxLatency', this.value) }
|
||||||
|
inp(doDisconnectTime).onchange = function () { updateOpts('disconnectTime', this.value) }
|
||||||
|
|
||||||
|
doPresetUrl.getElementsByTagName('select')[0].onchange = function () {
|
||||||
|
if (this.value) {
|
||||||
|
updateOpts('url', this.value)
|
||||||
|
inp(doUrl).value = this.value
|
||||||
|
initPlayer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initPlayer()
|
||||||
|
|
||||||
|
dbResetOpt.onclick = resetOpts
|
||||||
|
dbApplyOpt.onclick = initPlayer
|
||||||
|
dbPlay.onclick = function () { player.play() }
|
||||||
|
dbPause.onclick = function () { player.pause() }
|
||||||
|
dbReplay.onclick = function () { player.replay() }
|
||||||
|
dbDestroy.onclick = function () { player.destroy() }
|
||||||
|
dbSwitchUrl.onclick = function () {
|
||||||
|
var url = window.prompt('设置的 url 地址')
|
||||||
|
if (!url) return
|
||||||
|
var startTime = window.prompt('[点播]开始播放时间点', 0)
|
||||||
|
startTime = Number(startTime)
|
||||||
|
if (isNaN(startTime)) startTime = 0
|
||||||
|
player.switchURL(url, startTime)
|
||||||
|
}
|
||||||
|
dbSetUrl.onclick = function () {
|
||||||
|
var url = window.prompt('设置的 url 地址')
|
||||||
|
if (url) player.src = url
|
||||||
|
}
|
||||||
|
dbSeek.onclick = function () {
|
||||||
|
var time = window.prompt('设置的跳转到的事件点')
|
||||||
|
if (time == null) return
|
||||||
|
time = Number(time)
|
||||||
|
if (isNaN(time)) return
|
||||||
|
player.seek(time)
|
||||||
|
}
|
||||||
|
|
||||||
|
dTestPoint.onchange = function () {
|
||||||
|
localStorage.setItem('xg:test:hls:point', this.value)
|
||||||
|
resetOpts()
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
var lastPlayback = null
|
||||||
|
var fps = 0
|
||||||
|
var prevTime = 0
|
||||||
|
setInterval(function () {
|
||||||
|
if (player && player.plugins.hls) {
|
||||||
|
var t = player.currentTime
|
||||||
|
prevTime = t
|
||||||
|
var hls = player.plugins.hls.core
|
||||||
|
var buf = hls.bufferInfo()
|
||||||
|
var pq = hls.playbackQuality()
|
||||||
|
var sp = hls.speedInfo()
|
||||||
|
if (lastPlayback) {
|
||||||
|
fps = Math.round((pq.totalVideoFrames - lastPlayback.totalVideoFrames) / (pq.creationTime - lastPlayback.creationTime) * 1000)
|
||||||
|
}
|
||||||
|
lastPlayback = pq
|
||||||
|
|
||||||
|
dsBuffer.innerHTML =
|
||||||
|
'<p>当前时间:' + t + 's</p>' +
|
||||||
|
'<p>剩余缓存时长:' + buf.remaining + 's</p>' +
|
||||||
|
'<p>当前时间之前缓存时长:' + buf.behind + 's</p>' +
|
||||||
|
'<p>总缓存时长:' + buf.length + 's</p>' +
|
||||||
|
'<p>buffers:' + JSON.stringify(buf.buffers) + '</p>'
|
||||||
|
|
||||||
|
dsFrame.innerHTML =
|
||||||
|
'<p>总渲染帧数:' + pq.totalVideoFrames + '</p>' +
|
||||||
|
'<p>掉帧数量:' + pq.droppedVideoFrames + '</p>' +
|
||||||
|
'<p>fps:' + fps + '</p>'
|
||||||
|
|
||||||
|
dsSpeed.innerHTML =
|
||||||
|
'<p>当前速度:' + Math.round(sp.speed / (8 * 1024)) + 'KB/s</p>' +
|
||||||
|
'<p>平均速度:' + Math.round(sp.avgSpeed / (8 * 1024)) + 'KB/s</p>'
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
}
|
25
fixtures/mp4/index.js
Normal file
25
fixtures/mp4/index.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// import '../../packages/xgplayer-livevideo/src'
|
||||||
|
// import MP4Player from '../../packages/xgplayer-mp4/src'
|
||||||
|
import Player from '../../packages/xgplayer/src';
|
||||||
|
import Mp4Player from '../../packages/xgplayer-mp4/src';
|
||||||
|
|
||||||
|
// console.log(Player, Mp4Player)
|
||||||
|
let player=new Player({
|
||||||
|
id: 'vs',
|
||||||
|
autoplay: true,
|
||||||
|
volume: 0.3,
|
||||||
|
url:'./err.mp4',
|
||||||
|
poster: "//lf3-static.bytednsdoc.com/obj/eden-cn/nupenuvpxnuvo/xgplayer_doc/poster.jpg",
|
||||||
|
playsinline: true,
|
||||||
|
thumbnail: {
|
||||||
|
pic_num: 44,
|
||||||
|
width: 160,
|
||||||
|
height: 90,
|
||||||
|
col: 10,
|
||||||
|
row: 10,
|
||||||
|
// urls: ['//lf3-static.bytednsdoc.com/obj/eden-cn/nupenuvpxnuvo/xgplayer_doc/xgplayer-demo-thumbnail.jpg'],
|
||||||
|
},
|
||||||
|
height: window.innerHeight,
|
||||||
|
width: window.innerWidth,
|
||||||
|
plugins: [Mp4Player]
|
||||||
|
});
|
84
fixtures/music/index.js
Normal file
84
fixtures/music/index.js
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// import Player from 'xgplayer'
|
||||||
|
// // import '../../packages/xgplayer/dist/index.min.css'
|
||||||
|
// import MusicPreset, { Music, Analyze, Lyric } from '../../packages/xgplayer-music/src'
|
||||||
|
// import '../../packages/xgplayer-music/dist/index.min.css'
|
||||||
|
// window.player = new Player({
|
||||||
|
// id: 'vs',
|
||||||
|
// url: '',
|
||||||
|
// loop: false,
|
||||||
|
// autoplay: false,
|
||||||
|
// preloadTime:20,
|
||||||
|
// width: "100%",
|
||||||
|
// height: 70,
|
||||||
|
// controls: {
|
||||||
|
// mode: 'flex',
|
||||||
|
// initShow: true
|
||||||
|
// },
|
||||||
|
// music: {
|
||||||
|
// offline: true,
|
||||||
|
// list: [{
|
||||||
|
// vid: '1',
|
||||||
|
// src: './audio/1.mp3',
|
||||||
|
// title: '11111.mp3',
|
||||||
|
// poster: "https://p9-pc-sign.douyinpic.com/tos-cn-p-0015/ocAY2PfD40Q8Z5SHAdMg7IC8ebbRe7BEBn0CAa~tplv-dy-resize-origshort-autoq-75:330.jpeg?x-expires=1988096400&x-signature=jWrbLPoE8ow7fdCYyyeUWw2Oaf0%3D&from=3213915784&s=PackSourceEnum_FEED&se=false&sc=cover&biz_tag=pcweb_cover&l=20230103173048B1113E7290F15B007F0B"
|
||||||
|
// }, {
|
||||||
|
// vid: '2',
|
||||||
|
// src: './audio/2.mp3',
|
||||||
|
// title: '22222.mp3',
|
||||||
|
// poster: "https://p9-pc-sign.douyinpic.com/image-cut-tos-priv/12f35be1484d36bf1430bb46e4874589~tplv-dy-resize-origshort-autoq-75:330.jpeg?x-expires=1988096400&x-signature=wl1p8fpK09dXkS7uWO1qG1GRSPU%3D&from=3213915784&s=PackSourceEnum_FEED&se=false&sc=cover&biz_tag=pcweb_cover&l=20230103173048B1113E7290F15B007F0B"
|
||||||
|
// }, {
|
||||||
|
// vid: '3',
|
||||||
|
// src: './audio/3.mp3',
|
||||||
|
// title: '33333.mp3',
|
||||||
|
// poster: "https://p3-pc-sign.douyinpic.com/image-cut-tos-priv/9cd43ffa45bfe6b52e2847c8071f9b6f~tplv-dy-resize-origshort-autoq-75:330.jpeg?x-expires=1988096400&x-signature=I7QrHLEnZfMDjJtxjXPf0M7L00A%3D&from=3213915784&s=PackSourceEnum_FEED&se=false&sc=cover&biz_tag=pcweb_cover&l=20230103173048B1113E7290F15B007F0B"
|
||||||
|
// }, {
|
||||||
|
// vid: '4',
|
||||||
|
// src: './audio/4.mp3',
|
||||||
|
// title: '444444.mp3',
|
||||||
|
// poster: '//sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/music/poster-small.jpeg'
|
||||||
|
// }]
|
||||||
|
// },
|
||||||
|
// marginControls: true,
|
||||||
|
// // presets: ['default', MusicPreset],
|
||||||
|
// plugins: [Music],
|
||||||
|
// ignores: ['start', 'fullscreen', 'cssfullscreen', 'playbackrate'],
|
||||||
|
// mediaType: 'audio',
|
||||||
|
// videoConfig: {
|
||||||
|
// crossOrigin: 'anonymous'
|
||||||
|
// },
|
||||||
|
// mediaType: 'audio'
|
||||||
|
// });
|
||||||
|
// window.player.on('loadstart', (data) => {
|
||||||
|
// console.log('loadstart')
|
||||||
|
// })
|
||||||
|
|
||||||
|
// window.player.on('loadeddata', (data) => {
|
||||||
|
// console.log('loadeddata')
|
||||||
|
// })
|
||||||
|
|
||||||
|
// window.player.on('xglog', (data) => {
|
||||||
|
// console.log('[xglog]', data)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// window.player.on('user_action', (data) => {
|
||||||
|
// console.log('[user_action]', data)
|
||||||
|
// })
|
||||||
|
|
||||||
|
|
||||||
|
// function init() {
|
||||||
|
// window.analyze = new Analyze(player, document.querySelector('canvas'), {
|
||||||
|
// bgColor: 'rgba(0,0,0,0.65)',
|
||||||
|
// stroke: 1,
|
||||||
|
|
||||||
|
// })
|
||||||
|
// console.log('Analyze.MODES', Analyze.MODES)
|
||||||
|
// // analyze.mode = Analyze.MODES.DOU
|
||||||
|
// // player.on('playing', function(){
|
||||||
|
// // player.lyric (lyric, document.querySelector('#gc'));
|
||||||
|
// // player.__lyric__.show();
|
||||||
|
// // player.mode = 2;
|
||||||
|
// // });
|
||||||
|
// // document.getElementById("canvas").width = window.innerWidth;
|
||||||
|
// // document.getElementById("canvas").height = window.innerHeight * 0.36;
|
||||||
|
// }
|
||||||
|
// init()
|
94
fixtures/xgplayer/index.html
Normal file
94
fixtures/xgplayer/index.html
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="referrer" content="no-referrer" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Document</title>
|
||||||
|
<!-- <script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script>
|
||||||
|
<script>
|
||||||
|
var ua = navigator.userAgent.toLowerCase()
|
||||||
|
console.log('ua', ua, (ua.indexOf('mobile') > -1 || ua.indexOf('ipad') > -1) && location.href.indexOf('vconsole=1') > -1)
|
||||||
|
if ((ua.indexOf('mobile') > -1 || ua.indexOf('ipad') > -1) && location.href.indexOf('vconsole=1') > -1) {
|
||||||
|
var vConsole = new window.VConsole();
|
||||||
|
}
|
||||||
|
</script> -->
|
||||||
|
<style>
|
||||||
|
.pannel {
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 20px;
|
||||||
|
background: #72a0c8;
|
||||||
|
}
|
||||||
|
.message-pannel {
|
||||||
|
margin-top: 20px;
|
||||||
|
color: #333a3c;
|
||||||
|
}
|
||||||
|
.message-info {
|
||||||
|
margin-top: 20px;
|
||||||
|
border: 1px solid #728bb8;
|
||||||
|
padding: 10px 10px;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
margin-block-start: 0.2em;
|
||||||
|
margin-block-end: 0.2em;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
line-height: 18px;
|
||||||
|
display: block;
|
||||||
|
line-height: 16px;
|
||||||
|
/* margin: 10px; */
|
||||||
|
margin-block-start: 0.4em;
|
||||||
|
margin-block-end: 0.4em;
|
||||||
|
}
|
||||||
|
.ext-controls0 {
|
||||||
|
height: 80px !important;
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="video0"></div>
|
||||||
|
<div class="pannel">
|
||||||
|
<div class="tool">
|
||||||
|
<button type="submit" class="btn" id="js-destroy0" onclick="window.destroy(0)">
|
||||||
|
销毁
|
||||||
|
</button>
|
||||||
|
<button type="submit" class="btn" id="js-reinit0" onclick="window.init(0)">
|
||||||
|
重新初始化
|
||||||
|
</button>
|
||||||
|
<button type="submit" class="btn" id="js-playnext0" onclick="window.playNext(0)">
|
||||||
|
播放下一个
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn"
|
||||||
|
id="js-changelang0"
|
||||||
|
onclick="window.changeLang(0)"
|
||||||
|
>
|
||||||
|
切换语言
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn"
|
||||||
|
id="js-changelang0"
|
||||||
|
onclick="window.createDot(0)"
|
||||||
|
>
|
||||||
|
添加预览点
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="message-pannel">
|
||||||
|
<div class="message-info" id="js-show-lang0">
|
||||||
|
<h4>current lang:</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="message-info" id="js-show-log0">
|
||||||
|
<h4>log info:</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script></script>
|
||||||
|
<script type="module" defer src="./index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
283
fixtures/xgplayer/index.js
Normal file
283
fixtures/xgplayer/index.js
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
import Player from '../../packages/xgplayer/src/index'
|
||||||
|
import { TextTrack } from '../../packages/xgplayer/src/index'
|
||||||
|
import { I18N } from '../../packages/xgplayer/src'
|
||||||
|
|
||||||
|
// 全局配置语言
|
||||||
|
I18N.extend([
|
||||||
|
{
|
||||||
|
LANG: 'zh',
|
||||||
|
TEXT: {
|
||||||
|
PAUSE_TIPS: '暂停0',
|
||||||
|
PLAY_TIPS: '起播0'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LANG: 'en',
|
||||||
|
TEXT: {
|
||||||
|
PAUSE_TIPS: 'Pause0',
|
||||||
|
PLAY_TIPS: 'Play0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
window.player = null
|
||||||
|
window.player1 = null
|
||||||
|
function init(index = 0, config = {}) {
|
||||||
|
const p = `player${index}`
|
||||||
|
if (window[p]) {
|
||||||
|
window[p].destroy()
|
||||||
|
window[p] = null
|
||||||
|
}
|
||||||
|
window[p] = new Player({
|
||||||
|
id: 'video' + index,
|
||||||
|
url:
|
||||||
|
[{src:'https://lf3-static.bytednsdoc.com/obj/eden-cn/nupenuvpxnuvo/xgplayer_doc/xgplayer-demo-720p.mp4'},
|
||||||
|
{src:'https://lf3-static.bytednsdoc.com/obj/eden-cn/nupenuvpxnuvo/xgplayer_doc/xgplayer-demo-720p.mp4'},
|
||||||
|
{src:'https://lf3-static.bytednsdoc.com/obj/eden-cn/nupenuvpxnuvo/xgplayer_doc/xgplayer-demo-720p.mp4'}],
|
||||||
|
DynamicBg: {
|
||||||
|
disable: false
|
||||||
|
},
|
||||||
|
marginControls: false,
|
||||||
|
loop: false,
|
||||||
|
autoplay: false,
|
||||||
|
autoplayMuted: true,
|
||||||
|
videoInit: true,
|
||||||
|
preloadTime: 20,
|
||||||
|
width: '100%',
|
||||||
|
ignores:['playbackrate'],
|
||||||
|
plugins: [TextTrack],
|
||||||
|
// controls: {
|
||||||
|
// // mode: 'normal',
|
||||||
|
// // initShow: true
|
||||||
|
// },
|
||||||
|
progress: {
|
||||||
|
// root: document.getElementById('controls0')
|
||||||
|
},
|
||||||
|
volume: {
|
||||||
|
position: 'rootTop'
|
||||||
|
},
|
||||||
|
mobile: {
|
||||||
|
// gestureX: false
|
||||||
|
},
|
||||||
|
texttrack: {
|
||||||
|
debugger: false,
|
||||||
|
list: [{
|
||||||
|
label: '双语',
|
||||||
|
language: 'double',
|
||||||
|
id: '0',
|
||||||
|
isDefault: true,
|
||||||
|
url: '../subtitle/vtt/double.vtt', // [{url: './vtt/cn1.vtt'}, {url: './vtts/1-3.vtt'}, {url: './vtts/1-2.vtt'},{url: './vtts/1.vtt'}, {url: './vtts/2.vtt'}, {url: './vtts/3.vtt'},{url: './vtts/4.vtt'}, {url: './vtts/5.vtt'}, {url: './vtts/6.vtt'},{url: './vtts/7.vtt'},{url: './vtts/8.vtt'}]
|
||||||
|
// url: 'https://sf3-xgcdn-tos.pstatp.com/obj/tos-cn-o-0004/bc9bdde6738d4865a69da7f5afaafc87'
|
||||||
|
// url: './textTrack-1.vtt?de3fd3',
|
||||||
|
//url: 'http://lf1-xgcdn-tos.pstatp.com/obj/tos-cn-o-0004/52ce3882d70941d5b660913cbd83d969'
|
||||||
|
}, {
|
||||||
|
label: '中文',
|
||||||
|
language: 'cn',
|
||||||
|
id: '1',
|
||||||
|
isDefault: undefined,
|
||||||
|
//url: 'http://tosv.byted.org/obj/tos-cn-o-0004/0edaf77715f44faebe2e348f5157280a'
|
||||||
|
url: '../subtitle/vtt/cn.vtt'
|
||||||
|
//url: 'http://lf1-xgcdn-tos.pstatp.com/obj/tos-cn-o-0004/52ce3882d70941d5b660913cbd83d969'
|
||||||
|
//url: './ass/cn.ass'
|
||||||
|
}, {
|
||||||
|
label: '英文',
|
||||||
|
url: '../subtitle/vtt/en.vtt',
|
||||||
|
//url: 'http://lf6-xgcdn-tos.pstatp.com/obj/tos-cn-o-0004/d04fa4122dac42d69e8233a4dfda82fe',
|
||||||
|
// url: './ass/double.ass',
|
||||||
|
id: '2',
|
||||||
|
isDefault: false,
|
||||||
|
language: 'en'
|
||||||
|
}],
|
||||||
|
updateMode: 'vod',
|
||||||
|
isDefaultOpen: true,
|
||||||
|
mode: 'external',
|
||||||
|
},
|
||||||
|
definition: {
|
||||||
|
position: 'controlsLeft',
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
url: '//sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4',
|
||||||
|
definition: '360p',
|
||||||
|
text: '标清 360P',
|
||||||
|
iconText: '标清'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '//sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-480p.mp4',
|
||||||
|
definition: '480p',
|
||||||
|
text: {
|
||||||
|
zh: '高清 480P',
|
||||||
|
en: '480P'
|
||||||
|
},
|
||||||
|
iconText: '高清'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '//sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-720p.mp4',
|
||||||
|
definition: '720p',
|
||||||
|
text: {
|
||||||
|
zh: '超清 720P',
|
||||||
|
en: '720P'
|
||||||
|
},
|
||||||
|
iconText: '超清'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
defaultDefinition: '360p',
|
||||||
|
isItemClickHide: false
|
||||||
|
},
|
||||||
|
// 'definition': {
|
||||||
|
// 'text': '清晰度切换插件',
|
||||||
|
// 'type': 'array',
|
||||||
|
// 'checked': true,
|
||||||
|
// 'list': [
|
||||||
|
// { name: '超清', url: './media/msdv3.mp4' }]
|
||||||
|
// },
|
||||||
|
// width: 300,
|
||||||
|
height: 500,
|
||||||
|
...config
|
||||||
|
})
|
||||||
|
|
||||||
|
// window[p].usePluginHooks('progresspreview', 'transformTime', (plugin, time) => {
|
||||||
|
// plugin.setTimeContent(`~~${(time)}~~`)
|
||||||
|
|
||||||
|
// // 阻止插件内部默认钩子逻辑
|
||||||
|
// return false
|
||||||
|
// })
|
||||||
|
|
||||||
|
window[p].on('download_speed_change', data => {
|
||||||
|
console.log('[download_speed_change]', data)
|
||||||
|
// addLog(index, `[download_speed_change] speed:${data.speed}, realTimeSpeed:${data.realTimeSpeed || 0}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
window[p].on('xglog', data => {
|
||||||
|
console.log('[xglog]', data)
|
||||||
|
if (data.eventType === 'firstFrame' || data.eventType === 'waitingEnd') {
|
||||||
|
addLog(
|
||||||
|
index,
|
||||||
|
`[xglog] eventType:${data.eventType} ${data.costTime || 0} ${data.endType || ''}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
window.currentTime = 0
|
||||||
|
window[p].on('timeupdate', () => {
|
||||||
|
if (window[p].currentTime > currentTime) {
|
||||||
|
currentTime = window[p].currentTime
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// window[p].usePluginHooks('progress', 'dragstart', (plugin, event, data) =>{
|
||||||
|
// console.log('progress', data)
|
||||||
|
// // TODO
|
||||||
|
// if (data.currentTime > currentTime) {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// window[p].usePluginHooks('progress', 'drag', (plugin, event, data) =>{
|
||||||
|
// // TODO
|
||||||
|
// if (data.currentTime > currentTime) {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
window[p].on('user_action', data => {
|
||||||
|
console.log('[user_action]', data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
init()
|
||||||
|
|
||||||
|
// init(1, {
|
||||||
|
// i18n: [
|
||||||
|
// {
|
||||||
|
// LANG: 'zh',
|
||||||
|
// TEXT: {
|
||||||
|
// PLAY_TIPS: '播放1',
|
||||||
|
// PAUSE_TIPS: '暂停1',
|
||||||
|
// PAUSE_TIPS1: '测试1',
|
||||||
|
// CSSFULLSCREEN_TIPS: '网页全屏1'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// LANG: 'en',
|
||||||
|
// TEXT: {
|
||||||
|
// PLAY_TIPS: 'Play1',
|
||||||
|
// PAUSE_TIPS: 'Pause1',
|
||||||
|
// PAUSE_TIPS1: 'test1',
|
||||||
|
// CSSFULLSCREEN_TIPS: 'pagefullscreen1'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// enableContextmenu: true
|
||||||
|
// })
|
||||||
|
|
||||||
|
function addLog(index, mse) {
|
||||||
|
const logDom = document.getElementById(`js-show-log${index}`)
|
||||||
|
const p = document.createElement('p')
|
||||||
|
p.innerHTML = mse
|
||||||
|
logDom.appendChild(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearLog(index) {
|
||||||
|
const logDom = document.getElementById(`js-show-log${index}`)
|
||||||
|
const ps = logDom.getElementsByTagName('p')
|
||||||
|
let _len = ps.length
|
||||||
|
while (ps.length > 0) {
|
||||||
|
logDom.removeChild(ps[0])
|
||||||
|
_len--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeLang(index) {
|
||||||
|
const logDom = document.getElementById(`js-show-lang${index}`)
|
||||||
|
const p = logDom.getElementsByTagName('p')
|
||||||
|
const player = window[`player${index}`]
|
||||||
|
if (player.lang === 'zh') {
|
||||||
|
player.lang = 'en'
|
||||||
|
} else if (player.lang === 'en') {
|
||||||
|
player.lang = 'zh'
|
||||||
|
}
|
||||||
|
if (p.length === 0) {
|
||||||
|
const p = document.createElement('p')
|
||||||
|
p.innerHTML = player.lang
|
||||||
|
logDom.appendChild(p)
|
||||||
|
} else {
|
||||||
|
p[0].innerHTML = player.lang
|
||||||
|
}
|
||||||
|
console.log('p', p)
|
||||||
|
}
|
||||||
|
|
||||||
|
function playNext(index) {
|
||||||
|
console.log('playNext', index)
|
||||||
|
const p = `player${index}`
|
||||||
|
const config = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroy(index) {
|
||||||
|
console.log('destroy', index)
|
||||||
|
const p = `player${index}`
|
||||||
|
window[p] && window[p].destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
window.changeLang = changeLang
|
||||||
|
window.clearLog = clearLog
|
||||||
|
window.addLog = addLog
|
||||||
|
window.playNext = playNext
|
||||||
|
window.destroy = destroy
|
||||||
|
window.init = init
|
||||||
|
window.createDot = (index) => {
|
||||||
|
const player = window[`player${index}`]
|
||||||
|
const time = parseInt(Math.random(1) * player.duration, 10)
|
||||||
|
const duration = parseInt(Math.random(1) * 30 + 10, 10)
|
||||||
|
const ISPOT = {
|
||||||
|
time: time, // 进度条在此时间戳打点 单位为s
|
||||||
|
text: '', // 打点处的自定义文案
|
||||||
|
id: time, // 标记唯一标识,用于删除的时候索引
|
||||||
|
duration: duration, // 进度条标识点的时长 默认1s【可选】单位为s
|
||||||
|
color: '#fff', // 进度条标识点的显示颜色【可选】
|
||||||
|
style: {}, // 指定样式
|
||||||
|
width: 6,
|
||||||
|
height: 6
|
||||||
|
}
|
||||||
|
console.log(ISPOT)
|
||||||
|
player.plugins.progresspreview.createDot(ISPOT)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user