mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 02:46:16 -08:00
fix(playback): structure HTML5 mpegts errors
This commit is contained in:
1 parent
fc8fc4bdae
commit
2e3cde484d
3 files changed
+72
-3
No files matched your search
@@ -7,6 +7,7 @@ import {
|
||||
classifyMpegTsPlaybackIssue,
|
||||
classifyUnsupportedHlsManifestCodecs,
|
||||
createHlsPlaybackEvidence,
|
||||
createMpegTsPlaybackEvidence,
|
||||
createPlaybackSourceMetadata,
|
||||
} from '../playback-diagnostics/playback-diagnostics.util';
|
||||
|
||||
@@ -69,12 +70,16 @@ export function emitFatalHlsPlaybackError(
|
||||
|
||||
export function emitMpegTsPlaybackError(
|
||||
url: string,
|
||||
error: { type: string; details: string; info: unknown },
|
||||
error: { type: unknown; details: unknown; info: unknown },
|
||||
emitPlaybackIssue: (issue: PlaybackDiagnostic) => void
|
||||
): void {
|
||||
emitPlaybackIssue(
|
||||
classifyMpegTsPlaybackIssue(
|
||||
error,
|
||||
createMpegTsPlaybackEvidence(
|
||||
error.type,
|
||||
error.details,
|
||||
error.info
|
||||
),
|
||||
createHtml5SourceMetadata(url, 'video/mp2t')
|
||||
)
|
||||
);
|
||||
|
||||
+46
@@ -114,6 +114,52 @@ describe('HtmlVideoPlayerComponent shared controls sources', () => {
|
||||
}
|
||||
);
|
||||
|
||||
it('emits structured HTTP evidence for mpegts.js failures', () => {
|
||||
mpegTsIsSupported.mockReturnValue(true);
|
||||
const { component } = renderSharedControls(
|
||||
HtmlVideoPlayerComponent,
|
||||
fixtures,
|
||||
{
|
||||
channel: {
|
||||
...TEST_CHANNEL,
|
||||
url: 'https://example.test/missing.ts',
|
||||
},
|
||||
}
|
||||
);
|
||||
const issues: unknown[] = [];
|
||||
component.playbackIssue.subscribe((issue) => issues.push(issue));
|
||||
const secret = 'html-mpegts-secret';
|
||||
|
||||
mpegTsInstances[0].emit(
|
||||
'error',
|
||||
'NetworkError',
|
||||
'HttpStatusCodeInvalid',
|
||||
{
|
||||
code: 404,
|
||||
msg: `Not Found ${secret}`,
|
||||
url: `https://provider.example/error?token=${secret}`,
|
||||
}
|
||||
);
|
||||
|
||||
expect(issues).toEqual([
|
||||
expect.objectContaining({
|
||||
code: 'network-error',
|
||||
source: 'mpegts',
|
||||
sourceUrl: 'https://example.test/missing.ts',
|
||||
player: 'html5',
|
||||
httpStatus: 404,
|
||||
mpegTs: expect.objectContaining({
|
||||
engineType: 'NetworkError',
|
||||
engineDetails: 'HttpStatusCodeInvalid',
|
||||
failure: 'http',
|
||||
httpStatus: 404,
|
||||
}),
|
||||
externalFallbackRecommended: false,
|
||||
}),
|
||||
]);
|
||||
expect(JSON.stringify(issues)).not.toContain(secret);
|
||||
});
|
||||
|
||||
it('owns one MPEG-TS source between media attachment and loading', () => {
|
||||
mpegTsIsSupported.mockReturnValue(true);
|
||||
const { component } = renderSharedControls(
|
||||
|
||||
+19
-1
@@ -93,10 +93,22 @@ export class MockHls {
|
||||
}
|
||||
|
||||
export class MockMpegTsPlayer {
|
||||
private readonly listeners = new Map<
|
||||
string,
|
||||
Set<(...args: unknown[]) => void>
|
||||
>();
|
||||
readonly attachMediaElement = jest.fn(() =>
|
||||
lifecycle.push('mpegts:attachMedia')
|
||||
);
|
||||
readonly on = jest.fn();
|
||||
readonly on = jest.fn(
|
||||
(event: string, listener: (...args: unknown[]) => void) => {
|
||||
const listeners =
|
||||
this.listeners.get(event) ??
|
||||
new Set<(...args: unknown[]) => void>();
|
||||
listeners.add(listener);
|
||||
this.listeners.set(event, listeners);
|
||||
}
|
||||
);
|
||||
readonly load = jest.fn(() => lifecycle.push('mpegts:load'));
|
||||
readonly pause = jest.fn();
|
||||
readonly unload = jest.fn();
|
||||
@@ -106,6 +118,12 @@ export class MockMpegTsPlayer {
|
||||
constructor() {
|
||||
mpegTsInstances.push(this);
|
||||
}
|
||||
|
||||
emit(event: string, ...args: unknown[]): void {
|
||||
for (const listener of this.listeners.get(event) ?? []) {
|
||||
listener(...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const mpegTsCreatePlayer = jest.fn(() => new MockMpegTsPlayer());
|
||||
|
||||
Reference in new issue
Block a user