Skip to content
Open
Show file tree
Hide file tree
Changes from 18 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
1 change: 1 addition & 0 deletions packages/playback/src/lib/consts/text-tracks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const Thumbnails = 'thumbnails';
31 changes: 31 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,31 @@
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 !== '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 { 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 !== '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;
}
}
7 changes: 3 additions & 4 deletions packages/playback/src/lib/pipelines/base-pipeline.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { IPipeline, IPipelineDependencies } from '../types/pipeline.declarations';
import { PlayerTimeRange } from '../models/player-time-range';
import type { PlaybackState } from '../consts/playback-state';
import type { IPlaybackStats } from '../types/playback-stats.declarations';
import type { INetworkManager } from '../types/network.declarations';
import type { IQualityLevel } from '../types/quality-level.declarations';
Expand Down Expand Up @@ -46,8 +45,6 @@

public abstract getThumbnailTracks(): Array<IPlayerThumbnailTrack>;

public abstract getPlaybackState(): PlaybackState;

public abstract start(): void;

public getPlaybackStats(): IPlaybackStats {
Expand All @@ -71,7 +68,9 @@
}

public play(): void {
void this.videoElement_.play();
void this.videoElement_.play().catch((error) => {
this.logger_.error(error);
});

Check warning on line 73 in packages/playback/src/lib/pipelines/base-pipeline.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback/src/lib/pipelines/base-pipeline.ts#L71-L73

Added lines #L71 - L73 were not covered by tests
}

public seek(seekTarget: number): boolean {
Expand Down
71 changes: 54 additions & 17 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,72 @@
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 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 { Thumbnails } from '../../consts/text-tracks';

export class NativePipeline extends BasePipeline {
private constructor(dependencies: IPipelineDependencies) {
super(dependencies);
}

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 30 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#L30

Added line #L30 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);

// disable native track since there is no Track element to remove.
if (trackToRemove && trackToRemove.label.startsWith(Thumbnails)) {
trackToRemove.mode = '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('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 = 'hidden';
return true;
}
}
return false;
}

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

Check warning on line 71 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#L71

Added line #L71 was not covered by tests
}

public getAudioTracks(): Array<IPlayerAudioTrack> {
Expand Down Expand Up @@ -95,4 +124,12 @@
this.videoElement_.removeAttribute('src');
this.videoElement_.load();
}

public play(): void {
super.play();
}

Check warning on line 130 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#L129-L130

Added lines #L129 - L130 were not covered by tests

public pause(): void {
super.pause();
}

Check warning on line 134 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#L133-L134

Added lines #L133 - L134 were not covered by tests
}
8 changes: 8 additions & 0 deletions packages/playback/src/lib/player/base-player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@
this.activeVideoElement_.addEventListener('volumechange', this.handleVolumeChange_);
this.activeVideoElement_.addEventListener('ratechange', this.handleRateChange_);
this.activeVideoElement_.addEventListener('timeupdate', this.handleTimeUpdate_);
this.activeVideoElement_.addEventListener('waiting', this.handleWaiting_);

Check warning on line 403 in packages/playback/src/lib/player/base-player.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback/src/lib/player/base-player.ts#L403

Added line #L403 was not covered by tests
// EME
this.activeVideoElement_.addEventListener('encrypted', this.handleEncryptedEvent_);
this.activeVideoElement_.addEventListener('waitingforkey', this.handleWaitingForKeyEvent_);
Expand Down Expand Up @@ -428,6 +429,7 @@
this.activeVideoElement_.removeEventListener('volumechange', this.handleVolumeChange_);
this.activeVideoElement_.removeEventListener('ratechange', this.handleRateChange_);
this.activeVideoElement_.removeEventListener('timeupdate', this.handleTimeUpdate_);
this.activeVideoElement_.removeEventListener('waiting', this.handleWaiting_);

Check warning on line 432 in packages/playback/src/lib/player/base-player.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback/src/lib/player/base-player.ts#L432

Added line #L432 was not covered by tests
// EME
this.activeVideoElement_.removeEventListener('encrypted', this.handleEncryptedEvent_);
this.activeVideoElement_.removeEventListener('waitingforkey', this.handleWaitingForKeyEvent_);
Expand Down Expand Up @@ -575,6 +577,10 @@
this.eventEmitter_.emitEvent(new CurrentTimeChangedEvent(target.currentTime));
};

protected readonly handleWaiting_ = (): void => {
this.transitionPlaybackState_(PlaybackState.Buffering);
};

protected readonly handleEncryptedEvent_ = (event: MediaEncryptedEvent): void => {
this.logger_.debug('received encrypted event', event);

Expand Down Expand Up @@ -621,6 +627,7 @@
*/
public play(): void {
this.activeVideoElement_?.play();
this.transitionPlaybackState_(PlaybackState.Playing);
// TODO: pass command to loader/pipeline
}

Expand All @@ -629,6 +636,7 @@
*/
public pause(): void {
this.activeVideoElement_?.pause();
this.transitionPlaybackState_(PlaybackState.Paused);
// TODO: pass command to loader/pipeline
}

Expand Down
2 changes: 0 additions & 2 deletions packages/playback/src/lib/types/pipeline.declarations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { PlaybackState } from '../consts/playback-state';
import type { IPlaybackStats } from './playback-stats.declarations';
import type { ILogger } from './logger.declarations';
import type { INetworkManager } from './network.declarations';
Expand Down Expand Up @@ -47,7 +46,6 @@ export interface IPipelineFactoryConfiguration {
export interface IPipeline {
play(): void;
pause(): void;
getPlaybackState(): PlaybackState;
seek(seekTarget: number): boolean;
getSeekableRanges(): Array<IPlayerTimeRange>;
getBufferedRanges(): Array<IPlayerTimeRange>;
Expand Down
8 changes: 7 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,9 @@
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
Loading