Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/playback/src/lib/consts/text-tracks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export enum TextTrackKind {
Subtitles = 'subtitles',
Captions = 'captions',
Descriptions = 'descriptions',
Chapters = 'chapters',
Metadata = 'metadata',
// webkit only
Forced = 'forced',
}

export enum TextTrackMode {
Disabled = 'disabled',
Hidden = 'hidden',
Showing = 'showing',
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these 2 seem to match default text track interfaces, so you can simply use interfaces globally available in typescript via dom


export const Thumbnails = 'thumbnails';
32 changes: 32 additions & 0 deletions packages/playback/src/lib/models/player-text-tracks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { TextTrackKind } from '../consts/text-tracks';
import type { IPlayerTextTrack } from '../types/text-track.declarations';

export class PlayerTextTrack implements IPlayerTextTrack {
public readonly id: string;
public readonly activeCues: TextTrackCueList | null;
public readonly cues: TextTrackCueList | null;
public readonly kind: TextTrackKind;
public readonly label: string;
public readonly language: string;
public readonly mode: string;

public constructor(textTrack: TextTrack) {
this.id = textTrack.id;
this.activeCues = textTrack.activeCues;
this.cues = textTrack.cues;
this.kind = textTrack.kind as TextTrackKind;
this.label = textTrack.label;
this.language = textTrack.language;
this.mode = textTrack.mode;
}

public static fromTextTracks(textTrackList: TextTrackList): Array<PlayerTextTrack> {
const playerTextTracks = [];
for (let i = 0; i < textTrackList.length; i++) {
if (textTrackList[i].kind !== TextTrackKind.Metadata) {
playerTextTracks.push(new PlayerTextTrack(textTrackList[i]));
}
}
return playerTextTracks;
}
}
22 changes: 22 additions & 0 deletions packages/playback/src/lib/models/player-thumbnail-tracks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { TextTrackMode, Thumbnails } from '../consts/text-tracks';
import type { IPlayerThumbnailTrack } from '../types/thumbnail-track.declarations';
import { PlayerTextTrack } from './player-text-tracks';

export class PlayerThumbnailTrack extends PlayerTextTrack implements IPlayerThumbnailTrack {
public readonly isActive: boolean;

public constructor(textTrack: TextTrack) {
super(textTrack);
this.isActive = this.mode !== TextTrackMode.Disabled;
}

public static fromTextTracks(textTrackList: TextTrackList): Array<PlayerThumbnailTrack> {
const playerThumbnailTracks = [];
for (let i = 0; i < textTrackList.length; i++) {
if (textTrackList[i].label.startsWith(Thumbnails)) {
playerThumbnailTracks.push(new PlayerThumbnailTrack(textTrackList[i]));
}
}
return playerThumbnailTracks;
}
}
80 changes: 65 additions & 15 deletions packages/playback/src/lib/pipelines/native/native-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,81 @@ import type { IPipelineDependencies } from '../../types/pipeline.declarations';
import type { IPlayerAudioTrack } from '../../types/audio-track.declarations';
import { PlayerAudioTrack } from '../../models/player-audio-track';
import type { IQualityLevel } from '../../types/quality-level.declarations';
import type { PlaybackState } from 'src/lib/consts/playback-state';
import type { IPlayerTextTrack } from 'src/lib/types/text-track.declarations';
import type {
IRemoteVttThumbnailTrackOptions,
IPlayerThumbnailTrack,
} from 'src/lib/types/thumbnail-track.declarations';
import { PlaybackState } from '../../consts/playback-state';
import type { IPlayerTextTrack } from '../../types/text-track.declarations';
import {
type IRemoteVttThumbnailTrackOptions,
type IPlayerThumbnailTrack,
} from '../../types/thumbnail-track.declarations';
import { PlayerTextTrack } from '../../models/player-text-tracks';
import { PlayerThumbnailTrack } from '../../models/player-thumbnail-tracks';
import { TextTrackKind, TextTrackMode, Thumbnails } from '../../consts/text-tracks';

export class NativePipeline extends BasePipeline {
private playbackState_: PlaybackState = PlaybackState.Idle;

private constructor(dependencies: IPipelineDependencies) {
super(dependencies);
this.videoElement_.onwaiting = (): void => {
this.playbackState_ = PlaybackState.Buffering;
};
}

public static create(dependencies: IPipelineDependencies): NativePipeline {
dependencies.logger = dependencies.logger.createSubLogger('NativePipeline');

return new NativePipeline(dependencies);
}

public getTextTracks(): Array<IPlayerTextTrack> {
throw new Error('Method not implemented.');
if (this.videoElement_.textTracks) {
return PlayerTextTrack.fromTextTracks(this.videoElement_.textTracks);
}
return [];
}

// eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
public removeRemoteThumbnailTrack(id: string): boolean {
throw new Error('Method not implemented.');
if (this.videoElement_.textTracks) {
const trackToRemove = this.videoElement_.textTracks.getTrackById(id);
Comment thread
adrums86 marked this conversation as resolved.

// disable native track since there is no Track element to remove.
if (trackToRemove && trackToRemove.label.startsWith(Thumbnails)) {
trackToRemove.mode = TextTrackMode.Disabled;
return true;
}
}
return false;
}

// eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
public addRemoteVttThumbnailTrack(options: IRemoteVttThumbnailTrackOptions): boolean {
throw new Error('Method not implemented.');
// TODO: Request and parse thumbnails from VTT file or manifest.
if (options.url) {
this.videoElement_.addTextTrack(TextTrackKind.Metadata, Thumbnails);
return true;
}
return false;
}

// eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
public selectThumbnailTrack(id: string): boolean {
throw new Error('Method not implemented.');
if (this.videoElement_.textTracks) {
const trackToSelect = this.videoElement_.textTracks.getTrackById(id);

if (trackToSelect && trackToSelect.label.startsWith(Thumbnails)) {
trackToSelect.mode = TextTrackMode.Hidden;
return true;
}
}
return false;
}

public getThumbnailTracks(): Array<IPlayerThumbnailTrack> {
throw new Error('Method not implemented.');
if (this.videoElement_.textTracks) {
return PlayerThumbnailTrack.fromTextTracks(this.videoElement_.textTracks);
}
return [];
}
public getPlaybackState(): PlaybackState {
throw new Error('Method not implemented.');
return this.playbackState_;
}

public getAudioTracks(): Array<IPlayerAudioTrack> {
Expand Down Expand Up @@ -89,10 +127,22 @@ export class NativePipeline extends BasePipeline {

// TODO: check for autoplay/preload/etc
this.videoElement_.load();
this.playbackState_ = PlaybackState.Loading;
}

public dispose(): void {
this.videoElement_.removeAttribute('src');
this.videoElement_.load();
this.playbackState_ = PlaybackState.Idle;
}

public play(): void {
super.play();
this.playbackState_ = PlaybackState.Playing;
}

public pause(): void {
super.pause();
this.playbackState_ = PlaybackState.Paused;
}
}
10 changes: 9 additions & 1 deletion packages/playback/src/lib/types/text-track.declarations.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import type { TextTrackKind } from '../consts/text-tracks';

export interface IPlayerTextTrack {
id: string;
readonly id: string;
readonly activeCues: TextTrackCueList | null;
readonly cues: TextTrackCueList | null;
readonly kind: TextTrackKind;
readonly label: string;
readonly language: string;
readonly mode: string;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export interface IPlayerThumbnailTrack {
id: string;
import type { IPlayerTextTrack } from './text-track.declarations';

export interface IPlayerThumbnailTrack extends IPlayerTextTrack {
isActive: boolean;
}

Expand Down
Loading