Skip to content

Commit

Permalink
add an event "noPlayableTrack" to signal application that a currentMe…
Browse files Browse the repository at this point in the history
…dia has no track.
  • Loading branch information
Florent-Bouisset committed Jan 30, 2025
1 parent 923dac7 commit 5e29ebe
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 8 deletions.
18 changes: 18 additions & 0 deletions doc/api/Player_Events.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,24 @@ video track when in directfile mode to avoid that case (this is documented
in the corresponding APIs).
</div>

### noPlayableTrack

_payload type_: `Object`

Emitted when no tracks of a particular type can be selected for a period.

The payload is an object with the following properties:

- `trackType` (`"audio" | "video" | "text"`): The track type that appear to have no playable track.

- `period`: (`Object`): The period in which the track is not playable. The Object has the following properties:

- `id`: (`"string"`): The period id.

- `start`: (`"number"`): The period start time.

- `end`: (`"number" | undefined`): The period end time.

## Representation selection events

This chapter describes events linked to the current audio, video or Representation /
Expand Down
18 changes: 14 additions & 4 deletions src/main_thread/api/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ import type {
ITrackType,
IModeInformation,
IWorkerSettings,
INoPlayableTrackEventPayload,
} from "../../public_types";
import arrayFind from "../../utils/array_find";
import arrayIncludes from "../../utils/array_includes";
Expand All @@ -123,7 +124,11 @@ import {
getKeySystemConfiguration,
} from "../decrypt";
import type { ContentInitializer } from "../init";
import type { IMediaElementTracksStore, ITSPeriodObject } from "../tracks_store";
import type {
IMediaElementTracksStore,
INoPlayableTrack,

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / scripts_lint (20.x)

Module '"../tracks_store"' has no exported member 'INoPlayableTrack'. Did you mean to use 'import INoPlayableTrack from "../tracks_store"' instead?

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / scripts_lint (20.x)

'INoPlayableTrack' is declared but never used.

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / integration_linux (20.x)

Module '"../tracks_store"' has no exported member 'INoPlayableTrack'. Did you mean to use 'import INoPlayableTrack from "../tracks_store"' instead?

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / integration_linux (20.x)

'INoPlayableTrack' is declared but never used.

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / integration_linux (20.x)

Module '"../tracks_store"' has no exported member 'INoPlayableTrack'. Did you mean to use 'import INoPlayableTrack from "../tracks_store"' instead?

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / integration_linux (20.x)

'INoPlayableTrack' is declared but never used.

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / perf-tests

Module '"../tracks_store"' has no exported member 'INoPlayableTrack'. Did you mean to use 'import INoPlayableTrack from "../tracks_store"' instead?

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / perf-tests

'INoPlayableTrack' is declared but never used.

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / perf-tests

Module '"../tracks_store"' has no exported member 'INoPlayableTrack'. Did you mean to use 'import INoPlayableTrack from "../tracks_store"' instead?

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / perf-tests

'INoPlayableTrack' is declared but never used.

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / typechecking_and_linting (20.x)

Module '"../tracks_store"' has no exported member 'INoPlayableTrack'. Did you mean to use 'import INoPlayableTrack from "../tracks_store"' instead?

Check failure on line 129 in src/main_thread/api/public_api.ts

View workflow job for this annotation

GitHub Actions / typechecking_and_linting (20.x)

'INoPlayableTrack' is declared but never used.
ITSPeriodObject,
} from "../tracks_store";
import TracksStore from "../tracks_store";
import type { IParsedLoadVideoOptions, IParsedStartAtOption } from "./option_utils";
import {
Expand Down Expand Up @@ -2602,14 +2607,18 @@ class Player extends EventEmitter<IPublicAPIEvent> {
this._priv_onAvailableTracksMayHaveChanged(e.trackType);
}
});
contentInfos.tracksStore.addEventListener("warning", (err) => {
tracksStore.addEventListener("warning", (err) => {
this.trigger("warning", err);
});
contentInfos.tracksStore.addEventListener("error", (err) => {
tracksStore.addEventListener("error", (err) => {
this._priv_onFatalError(err, contentInfos);
});

contentInfos.tracksStore.onManifestUpdate(manifest);
tracksStore.addEventListener("noPlayableTrack", (trackType) => {
this.trigger("noPlayableTrack", trackType);
});

tracksStore.onManifestUpdate(manifest);
}

/**
Expand Down Expand Up @@ -3368,6 +3377,7 @@ interface IPublicAPIEvent {
streamEvent: IStreamEvent;
streamEventSkip: IStreamEvent;
inbandEvents: IInbandEvent[];
noPlayableTrack: INoPlayableTrackEventPayload;
}

/** State linked to a particular contents loaded by the public API. */
Expand Down
35 changes: 31 additions & 4 deletions src/main_thread/tracks_store/tracks_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ export default class TracksStore extends EventEmitter<ITracksStoreEvents> {

/**
* Handle the noPlayableRepresentation event, trigger an error if no fallback is possible.
* and can trigger event "noPlayableTracks"
* and can trigger event "noPlayableTrack"
* @param period - The period that has no playable representation
* @param bufferType - The media type that is not playable
*/
Expand Down Expand Up @@ -538,22 +538,39 @@ export default class TracksStore extends EventEmitter<ITracksStoreEvents> {
) {
// Audio is not playable but video may be playable, let's continue the playback.
log.warn(`TS: No playable audio, continuing without audio`);
this.trigger("noPlayableTracks", bufferType);
this.trigger("noPlayableTrack", {
trackType: bufferType,
period: { id: period.id, start: period.start, end: period.end },
});
} else if (
firstPlayableAdaptation === undefined &&
bufferType === "video" &&
this.onVideoTracksNotPlayable === "continue"
) {
// Video is not playable but audio may be playable, let's continue the playback.
log.warn(`TS: No playable video, continuing with audio only`);
this.trigger("noPlayableTracks", bufferType);
this.trigger("noPlayableTrack", {
trackType: bufferType,
period: {
id: period.id,
start: period.start,
end: period.end,
},
});
} else if (firstPlayableAdaptation === undefined) {
const noRepErr = new MediaError(
"NO_PLAYABLE_REPRESENTATION",
`No ${bufferType} Representation can be played`,
{ tracks: undefined },
);
this.trigger("noPlayableTracks", bufferType);
this.trigger("noPlayableTrack", {
trackType: bufferType,
period: {
id: period.id,
start: period.start,
end: period.end,
},
});
this.trigger("error", noRepErr);
this.dispose();
return;
Expand Down Expand Up @@ -1760,6 +1777,16 @@ interface ITracksStoreEvents {
trackUpdate: ITrackUpdateEventPayload;
error: unknown;
warning: IPlayerError;
noPlayableTrack: INoPlayableTrack;
}

interface INoPlayableTrack {
trackType: ITrackType;
period: {
id: string;
start: number;
end: number | undefined;
};
}

export interface IAudioRepresentationsLockSettings {
Expand Down
9 changes: 9 additions & 0 deletions src/public_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,15 @@ export interface ITrackUpdateEventPayload {
/* eslint-enable @typescript-eslint/no-redundant-type-constituents */
}

export interface INoPlayableTrackEventPayload {
trackType: ITrackType;
period: {
id: string;
start: number;
end: number | undefined;
};
}

export interface IRepresentationListUpdateContext {
period: IPeriod;
trackType: ITrackType;
Expand Down

0 comments on commit 5e29ebe

Please sign in to comment.