mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-28 02:01:20 -08:00
refactor(auto-thumbnail): [PKG-AUTO-THUMB-03] wait for native frame presentation
This commit is contained in:
1 parent
a128706fe7
commit
8c57d56f17
21 files changed
+10716
-296
No files matched your search
@@ -5,14 +5,14 @@ import { expect, test } from './fixtures.js'
|
||||
const implementation = await autoThumbnailCandidate()
|
||||
|
||||
for (const media of ['auto-thumbnail-timeline', 'pattern']) {
|
||||
test(`Auto-thumbnail candidate retains cells 2-4 ${media} pixels in a hidden decoder`, async ({ page, browserName }, testInfo) => {
|
||||
test(`Auto-thumbnail candidate verifies presented ${media} pixels and records fallback limits`, async ({ page, browserName }, testInfo) => {
|
||||
await page.goto('/test/player.html?core=published')
|
||||
await page.setContent('<!doctype html><style>video { width: 1px; height: 1px; max-width: 1px; max-height: 1px; display: none }</style>')
|
||||
await page.addScriptTag({ content: implementation.code })
|
||||
await page.evaluate(async (media) => {
|
||||
const createElement = document.createElement.bind(document)
|
||||
const drawImage = CanvasRenderingContext2D.prototype.drawImage
|
||||
const probe = window.probe = { videos: [], updates: [], draws: [], playing: 0, warnings: [] }
|
||||
const probe = window.probe = { videos: [], updates: [], draws: [], presented: [], playing: 0, warnings: [] }
|
||||
const warn = console.warn
|
||||
console.warn = (...args) => probe.warnings.push(args.map(String))
|
||||
document.createElement = function (tag, ...args) {
|
||||
@@ -20,6 +20,13 @@ for (const media of ['auto-thumbnail-timeline', 'pattern']) {
|
||||
if (tag === 'video') {
|
||||
probe.videos.push(element)
|
||||
element.addEventListener('playing', () => probe.playing++)
|
||||
const request = element.requestVideoFrameCallback?.bind(element)
|
||||
if (request) {
|
||||
element.requestVideoFrameCallback = callback => request((now, metadata) => {
|
||||
probe.presented.push({ mediaTime: metadata.mediaTime, currentTime: element.currentTime })
|
||||
callback(now, metadata)
|
||||
})
|
||||
}
|
||||
}
|
||||
return element
|
||||
}
|
||||
@@ -79,15 +86,17 @@ for (const media of ['auto-thumbnail-timeline', 'pattern']) {
|
||||
const final = probe.videos.map(video => ({ connected: video.isConnected, src: video.getAttribute('src'), paused: video.paused }))
|
||||
probe.art.emit('destroy')
|
||||
probe.restore()
|
||||
return { cells, spatial, draws: probe.draws, final, playing: probe.playing, warnings: probe.warnings }
|
||||
const supportsPresentation = typeof probe.videos[0].requestVideoFrameCallback === 'function' && typeof probe.videos[0].cancelVideoFrameCallback === 'function'
|
||||
return { cells, spatial, draws: probe.draws, presented: probe.presented, supportsPresentation, final, playing: probe.playing, warnings: probe.warnings }
|
||||
})
|
||||
await testInfo.attach('auto-thumbnail-candidate-hidden-pixels', { contentType: 'application/json', body: JSON.stringify({
|
||||
sha256: hash(implementation.code),
|
||||
media,
|
||||
scope: 'Native decoding and JPEG pixels for cells 2-4, hidden intrinsic-sized rendering and cleanup. Cells 0-1 are diagnostic only: initial drawing/readiness/timestamp behavior remains open under AUTO-THUMB-PIXEL-01. Stub player host, not a core integration.',
|
||||
scope: 'All five cells are asserted where native frame presentation callbacks are available. Without that capability only cells 2-4 are asserted, with cells 0-1 recorded as unresolved diagnostics under AUTO-THUMB-PIXEL-01. Native HTTP/JPEG and a stub player host, not a core integration.',
|
||||
...state,
|
||||
}) })
|
||||
testInfo.annotations.push({ type: 'remaining-initial-frame-risk', description: `${browserName}: cells 0-1 are evidence only; this test cannot close AUTO-THUMB-PIXEL-01 or PKG-AUTO-THUMB-03.` })
|
||||
if (!state.supportsPresentation)
|
||||
testInfo.annotations.push({ type: 'remaining-initial-frame-risk', description: `${browserName}: no native presentation callback; cells 0-1 remain evidence only and cannot close AUTO-THUMB-PIXEL-01 or PKG-AUTO-THUMB-03.` })
|
||||
expect(state.warnings).toEqual([])
|
||||
expect(state.playing).toBe(0)
|
||||
expect(state.final).toEqual([{ connected: false, src: null, paused: true }])
|
||||
@@ -98,12 +107,25 @@ for (const media of ['auto-thumbnail-timeline', 'pattern']) {
|
||||
expect(draw.display).toBe('block')
|
||||
expect(draw.width).toBeGreaterThanOrEqual(80)
|
||||
expect(draw.height).toBeGreaterThanOrEqual(45)
|
||||
if (index > 1) {
|
||||
if (state.supportsPresentation || index > 1) {
|
||||
expect(Math.abs(draw.time - draw.duration * index / 5)).toBeLessThan(0.05)
|
||||
expect(draw.raw[3]).toBe(255)
|
||||
}
|
||||
}
|
||||
if (state.supportsPresentation) {
|
||||
expect(state.presented).toHaveLength(5)
|
||||
for (const [index, frame] of state.presented.entries())
|
||||
expect(Math.abs(frame.mediaTime - state.draws[index].duration * index / 5)).toBeLessThan(0.06)
|
||||
}
|
||||
if (media === 'auto-thumbnail-timeline') {
|
||||
if (state.supportsPresentation) {
|
||||
const [purple, red] = state.cells
|
||||
expect(Math.min(purple[0], purple[2])).toBeGreaterThan(100)
|
||||
expect(Math.abs(purple[0] - purple[2])).toBeLessThan(30)
|
||||
expect(purple[1]).toBeLessThan(40)
|
||||
expect(red[0]).toBeGreaterThan(200)
|
||||
expect(Math.max(red[1], red[2])).toBeLessThan(40)
|
||||
}
|
||||
const [black, blue, yellow] = state.cells.slice(2)
|
||||
expect(Math.max(...black.slice(0, 3))).toBeLessThan(30)
|
||||
expect(blue[2]).toBeGreaterThan(200)
|
||||
@@ -112,7 +134,7 @@ for (const media of ['auto-thumbnail-timeline', 'pattern']) {
|
||||
expect(yellow[2]).toBeLessThan(40)
|
||||
}
|
||||
else {
|
||||
for (const pixel of state.cells.slice(2, 4)) {
|
||||
for (const pixel of state.cells.slice(state.supportsPresentation ? 0 : 2, 4)) {
|
||||
expect(pixel[2] - Math.max(pixel[0], pixel[1])).toBeGreaterThan(80)
|
||||
}
|
||||
expect(state.cells[4][0] - Math.max(state.cells[4][1], state.cells[4][2])).toBeGreaterThan(80)
|
||||
|
||||
Reference in new issue
Block a user