Skip to content
Open
Show file tree
Hide file tree
Changes from 12 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
2 changes: 1 addition & 1 deletion .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1 +1 @@
npm test
npm run test
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
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 } 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;
}
}
81 changes: 66 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,82 @@
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 [];

Check warning on line 36 in packages/playback/src/lib/pipelines/native/native-pipeline.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback/src/lib/pipelines/native/native-pipeline.ts#L36

Added line #L36 was not covered by tests
}

// 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);

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

Check warning on line 50 in packages/playback/src/lib/pipelines/native/native-pipeline.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback/src/lib/pipelines/native/native-pipeline.ts#L50

Added line #L50 was not covered by tests
}

// 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.
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.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 [];

Check warning on line 78 in packages/playback/src/lib/pipelines/native/native-pipeline.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback/src/lib/pipelines/native/native-pipeline.ts#L78

Added line #L78 was not covered by tests
}
public getPlaybackState(): PlaybackState {
throw new Error('Method not implemented.');
return this.playbackState_;
}

public getAudioTracks(): Array<IPlayerAudioTrack> {
Expand Down Expand Up @@ -89,10 +128,22 @@

// 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