mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-09 03:17:46 -08:00
144 lines
9.2 KiB
JavaScript
144 lines
9.2 KiB
JavaScript
import { useAudioFixture } from './audio-fixture.js'
|
|
import { expect, test } from './fixtures.js'
|
|
|
|
const { openAudio } = useAudioFixture()
|
|
|
|
for (const core of ['published', 'candidate']) {
|
|
for (const plugin of ['published', 'source']) {
|
|
test(`${core} core + ${plugin} audio: rapid main/audio switches settle on the last pair`, async ({ page }, testInfo) => {
|
|
await openAudio(page, core, plugin, testInfo)
|
|
await page.locator('#play').click()
|
|
await expect.poll(() => page.evaluate(() => window.audioPlugin.audio.currentTime)).toBeGreaterThan(0.3)
|
|
await page.evaluate(async () => {
|
|
const { art, audioPlugin } = window
|
|
window.originalAudio = audioPlugin.audio
|
|
const pending = []
|
|
for (const source of ['first', 'second', 'last']) {
|
|
pending.push(art.switchUrl(`/test/pattern.mp4?pair=${source}`))
|
|
audioPlugin.update({ url: `/test/audio-tone.m4a?pair=${source}` })
|
|
}
|
|
await Promise.all(pending)
|
|
})
|
|
await expect.poll(() => page.evaluate(() => window.art.video.currentSrc)).toContain('pair=last')
|
|
await expect.poll(() => page.evaluate(() => window.audioPlugin.audio.currentSrc)).toContain('pair=last')
|
|
await expect.poll(() => page.evaluate(() => !window.art.video.paused && !window.audioPlugin.audio.paused && window.art.currentTime > 0.3)).toBe(true)
|
|
await expect.poll(() => page.evaluate(() => Math.abs(window.art.currentTime - window.audioPlugin.audio.currentTime))).toBeLessThan(0.5)
|
|
expect(await page.evaluate(() => window.originalAudio === window.audioPlugin.audio)).toBe(true)
|
|
await page.evaluate(async () => {
|
|
window.art.pause()
|
|
await window.art.switchUrl('/test/pattern.mp4?pair=paused')
|
|
window.audioPlugin.update({ url: '/test/audio-tone.m4a?pair=paused' })
|
|
})
|
|
await expect.poll(() => page.evaluate(() => window.audioPlugin.audio.readyState)).toBeGreaterThanOrEqual(2)
|
|
expect(await page.evaluate(() => window.art.video.paused && window.audioPlugin.audio.paused)).toBe(true)
|
|
await page.locator('#play').click()
|
|
await expect.poll(() => page.evaluate(() => window.audioPlugin.audio.currentTime)).toBeGreaterThan(0.3)
|
|
expect(await page.evaluate(() => [window.art.video.error, window.audioPlugin.audio.error])).toEqual([null, null])
|
|
await page.evaluate(() => window.art.destroy())
|
|
})
|
|
|
|
test(`${core} core + ${plugin} audio: two active players keep clocks and ownership independent`, async ({ page }, testInfo) => {
|
|
await openAudio(page, core, plugin, testInfo)
|
|
await page.evaluate(() => {
|
|
window.art.option.mutex = false
|
|
const container = document.createElement('div')
|
|
container.style.cssText = 'width:320px;height:180px'
|
|
document.body.append(container)
|
|
window.otherArt = new window.Artplayer({ container, url: '/test/pattern.mp4?instance=other', mutex: false, muted: true, plugins: [window.artplayerPluginAudioTrack({ url: '/test/audio-tone.m4a?instance=other', offset: 0.5, sync: 0.1 })] })
|
|
window.otherAudio = window.otherArt.plugins.artplayerPluginAudioTrack.audio
|
|
const play = document.querySelector('#play')
|
|
play.onclick = () => Promise.all([window.art.play(), window.otherArt.play()])
|
|
})
|
|
await expect.poll(() => page.evaluate(() => window.otherArt.isReady && window.otherAudio.readyState >= 2)).toBe(true)
|
|
await page.locator('#play').click()
|
|
await expect.poll(() => page.evaluate(() => !window.audioPlugin.audio.paused && !window.otherAudio.paused && window.art.currentTime > 0.2 && window.otherArt.currentTime > 0.2)).toBe(true)
|
|
await page.evaluate(() => {
|
|
window.art.pause()
|
|
window.art.seek = 3
|
|
window.art.volume = 0.2
|
|
window.art.playbackRate = 1.5
|
|
window.otherArt.volume = 0.7
|
|
})
|
|
await expect.poll(() => page.evaluate(() => window.audioPlugin.audio.currentTime)).toBeCloseTo(3, 1)
|
|
await expect.poll(() => page.evaluate(() => window.audioPlugin.audio.playbackRate)).toBe(1.5)
|
|
await expect.poll(() => page.evaluate(() => window.otherAudio.volume)).toBeCloseTo(0.7)
|
|
expect(await page.evaluate(() => window.otherAudio.playbackRate)).toBe(1)
|
|
expect(await page.evaluate(() => window.otherAudio !== window.audioPlugin.audio)).toBe(true)
|
|
await expect.poll(() => page.evaluate(() => Math.abs(window.otherAudio.currentTime - window.otherArt.currentTime - 0.5))).toBeLessThan(0.5)
|
|
const before = await page.evaluate(() => {
|
|
window.art.destroy()
|
|
return window.otherAudio.currentTime
|
|
})
|
|
await expect.poll(() => page.evaluate(() => window.otherAudio.currentTime)).toBeGreaterThan(before + 0.3)
|
|
expect(await page.evaluate(() => window.audioPlugin.audio.paused && !window.otherAudio.paused)).toBe(true)
|
|
expect(await page.evaluate(() => window.otherAudio.currentSrc)).toContain('instance=other')
|
|
expect(await page.evaluate(() => window.otherAudio.error)).toBeNull()
|
|
await testInfo.attach('independent-audio', { contentType: 'application/json', body: JSON.stringify(await page.evaluate(() => ({ left: { time: window.audioPlugin.audio.currentTime, paused: window.audioPlugin.audio.paused, rate: window.audioPlugin.audio.playbackRate }, right: { time: window.otherAudio.currentTime, videoTime: window.otherArt.currentTime, rate: window.otherAudio.playbackRate, paused: window.otherAudio.paused } }))) })
|
|
await page.evaluate(() => window.otherArt.destroy())
|
|
expect(await page.evaluate(() => window.otherAudio.paused)).toBe(true)
|
|
})
|
|
|
|
test(`${core} core + ${plugin} audio: native offset bounds recover to an in-range seek`, async ({ page }, testInfo) => {
|
|
await openAudio(page, core, plugin, testInfo)
|
|
await page.evaluate(() => {
|
|
window.boundaryAudio = new Audio('/test/audio-tone.m4a?boundary=native')
|
|
window.boundaryAudio.muted = true
|
|
document.querySelector('#play').onclick = () => Promise.all([window.art.play(), window.boundaryAudio.play()])
|
|
})
|
|
await expect.poll(() => page.evaluate(() => window.boundaryAudio.readyState)).toBeGreaterThanOrEqual(2)
|
|
await page.locator('#play').click()
|
|
await expect.poll(() => page.evaluate(() => window.audioPlugin.audio.currentTime)).toBeGreaterThan(0.2)
|
|
await page.evaluate(() => {
|
|
window.art.pause()
|
|
window.boundaryAudio.pause()
|
|
window.audioPlugin.update({ offset: -2 })
|
|
window.art.seek = 0.5
|
|
window.boundaryAudio.currentTime = -1.5
|
|
})
|
|
await expect.poll(() => page.evaluate(() => !window.art.video.seeking && !window.audioPlugin.audio.seeking && !window.boundaryAudio.seeking)).toBe(true)
|
|
const negative = await page.evaluate(() => {
|
|
const state = audio => ({ time: audio.currentTime, error: audio.error?.code || null })
|
|
return { audio: state(window.audioPlugin.audio), native: state(window.boundaryAudio) }
|
|
})
|
|
await testInfo.attach('negative-offset-native', { contentType: 'application/json', body: JSON.stringify(negative) })
|
|
expect(negative.native.time).toBeGreaterThanOrEqual(0)
|
|
expect(negative.native.time).toBeCloseTo(0, 1)
|
|
expect(negative.audio.time).toBeGreaterThanOrEqual(0)
|
|
expect(negative.audio.time).toBeCloseTo(negative.native.time, 1)
|
|
expect([negative.audio.error, negative.native.error]).toEqual([null, null])
|
|
await page.evaluate(() => {
|
|
window.audioPlugin.update({ offset: 20 })
|
|
window.art.seek = 1
|
|
window.boundaryAudio.currentTime = 21
|
|
})
|
|
await expect.poll(() => page.evaluate(() => !window.art.video.seeking && !window.audioPlugin.audio.seeking && !window.boundaryAudio.seeking)).toBe(true)
|
|
const overflow = await page.evaluate(() => {
|
|
const state = audio => ({ time: audio.currentTime, duration: audio.duration, error: audio.error?.code || null })
|
|
return { audio: state(window.audioPlugin.audio), native: state(window.boundaryAudio) }
|
|
})
|
|
await testInfo.attach('overflow-offset-native', { contentType: 'application/json', body: JSON.stringify(overflow) })
|
|
expect(overflow.native.duration).toBe(16)
|
|
expect(overflow.native.time).toBeCloseTo(overflow.native.duration, 1)
|
|
expect(overflow.audio.time).toBeCloseTo(overflow.native.time, 1)
|
|
expect([overflow.audio.error, overflow.native.error]).toEqual([null, null])
|
|
expect(await page.evaluate(() => window.audioPlugin.audio.paused)).toBe(true)
|
|
await page.evaluate(() => {
|
|
window.audioPlugin.update({ offset: -0.5 })
|
|
window.art.seek = 3
|
|
window.boundaryAudio.currentTime = 2.5
|
|
})
|
|
await expect.poll(() => page.evaluate(() => window.audioPlugin.audio.currentTime)).toBeCloseTo(2.5, 1)
|
|
await page.locator('#play').click()
|
|
await expect.poll(() => page.evaluate(() => window.audioPlugin.audio.currentTime)).toBeGreaterThan(2.8)
|
|
await expect.poll(() => page.evaluate(() => Math.abs(window.audioPlugin.audio.currentTime - window.art.currentTime + 0.5))).toBeLessThan(0.5)
|
|
await testInfo.attach('offset-boundary', { contentType: 'application/json', body: JSON.stringify({ negative, overflow, recovered: true }) })
|
|
await page.evaluate(() => {
|
|
window.art.destroy()
|
|
window.boundaryAudio.pause()
|
|
window.boundaryAudio.removeAttribute('src')
|
|
window.boundaryAudio.load()
|
|
})
|
|
})
|
|
}
|
|
}
|