Skip to content

Commit

Permalink
fix(FEC-9523): add attach detach implemention (#21)
Browse files Browse the repository at this point in the history
for reloading media add attach detach implemention.
Simulate event as exist in HTML5 on destroy.
  • Loading branch information
Yuvalke committed Dec 30, 2019
1 parent 2d72e06 commit ba59a7e
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 68 deletions.
47 changes: 24 additions & 23 deletions src/flash.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,16 @@ class Flash extends FakeEventTarget implements IEngine {
*/
_api: ?FlashHLSAdapter = null;

/**
* The src
* @type {string}
* @private
*/
_src: ?string = null;

/**
* The player config object.
* @type {Object}
* @type {?Object}
* @private
*/
_config: ?Object = null;
_config: ?Object;

/**
* Promise when load finished
* @type {Promise<*>}
* @type {?Promise<*>}
* @private
*/
_loadPromise: ?Promise<*> = null;
Expand All @@ -70,13 +63,11 @@ class Flash extends FakeEventTarget implements IEngine {

/**
* The event manager of the engine.
* @type {EventManager}
* @type {?EventManager}
* @private
*/
_eventManager: EventManager = null;

_srcToLoad: ?string = null;

/**
* The state of player mute
* @type {boolean}
Expand Down Expand Up @@ -185,9 +176,17 @@ class Flash extends FakeEventTarget implements IEngine {
this._init(source, config);
}

attachMediaSource(): void {}
attachMediaSource(): void {
if (this._api) {
this._api.attachMediaSource();
}
}

detachMediaSource(): void {}
detachMediaSource(): void {
if (this._api) {
this._api.detachMediaSource();
}
}

hideTextTrack(): void {}

Expand All @@ -204,20 +203,18 @@ class Flash extends FakeEventTarget implements IEngine {
this._api = new FlashHLSAdapter(source, config, this._el);
this._api.attach();
this._addBindings();
this._srcToLoad = source.url;
}
}

reset(): void {
if (this._api) {
this._api.reset();
}
this._src = null;

this._config = null;
this._muted = this.defaultMuted;
this._volume = NaN;
this._volumeBeforeMute = NaN;
this._srcToLoad = null;
}

/**
Expand Down Expand Up @@ -303,8 +300,11 @@ class Flash extends FakeEventTarget implements IEngine {
EventType.SEEKING,
EventType.SEEKED,
EventType.ENDED,
EventType.TEXT_CUE_CHANGED,
EventType.VIDEO_TRACK_CHANGED,
EventType.AUDIO_TRACK_CHANGED,
EventType.ABORT,
EventType.EMPTIED,
EventType.DURATION_CHANGE
];
events.forEach(eventName => {
Expand Down Expand Up @@ -384,7 +384,9 @@ class Flash extends FakeEventTarget implements IEngine {
* @returns {void}
*/
set src(source: string): void {
this._src = source;
if (this._api) {
this._api.src = source;
}
}

/**
Expand All @@ -393,15 +395,15 @@ class Flash extends FakeEventTarget implements IEngine {
* @public
*/
get src(): string {
if (this._src) {
return this._src;
if (this._api) {
return this._api.src;
}
return '';
}

/**
* Load media.
* @param {number} startTime - Optional time to start the video from.
* @param {?number} startTime - Optional time to start the video from.
* @public
* @returns {Promise<Object>} - The loaded data
*/
Expand All @@ -410,7 +412,6 @@ class Flash extends FakeEventTarget implements IEngine {
Flash._logger.warn('Missing API - Flash is not ready');
return Promise.reject('Flash is not ready');
}
this._src = this._srcToLoad;
this._loadPromise = this._api.load(startTime);
return this._loadPromise;
}
Expand Down
169 changes: 124 additions & 45 deletions src/flashhls-adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import DefaultConfig from './default-config';
class FlashHLSAdapter extends FakeEventTarget {
_config: Object;
_el: HTMLDivElement;
_api: FlashAPI;
_api: ?FlashAPI;
_src: PKMediaSourceObject;
_startTime: number;
_firstPlay: boolean = true;
Expand All @@ -18,10 +18,24 @@ class FlashHLSAdapter extends FakeEventTarget {
duration: ?number;
buffer: ?number;
watched: ?number;
currentTime: ?number;
currentTime: number;
_apiLoadPromise: Promise<*>;
_apiLoadResolve: any;

/**
* The last time detach occurred
* @type {number}
* @private
*/
_lastTimeDetach: number = NaN;

/**
* The start time after attach
* @type {number}
* @private
*/
_startTimeAttach: number = NaN;

static getFlashCode(swf: string, flashVars: Object, params: Object, attributes: Object): string {
const objTag = '<object type="application/x-shockwave-flash" ';
let flashVarsString = '';
Expand Down Expand Up @@ -92,6 +106,17 @@ class FlashHLSAdapter extends FakeEventTarget {
if (this._el && this._el.parentNode) {
this._el.innerHTML = '';
}
this._startTimeAttach = NaN;
this._lastTimeDetach = NaN;
this._api = null;
//simulate the event sequence like video tag
this._trigger(EventType.ABORT);
this._trigger(EventType.EMPTIED);
//to hide the text tracks simulate event like happened in hls.js
this._trigger(EventType.TEXT_CUE_CHANGED, {cues: []});

this.currentTime = NaN;
this._trigger(EventType.TIME_UPDATE);
}

attach(): HTMLDivElement {
Expand All @@ -107,8 +132,10 @@ class FlashHLSAdapter extends FakeEventTarget {
if (this._initialVolume != null) {
this.volume(this._initialVolume);
}
if (this._config.debug) {
if (this._api && this._config.debug) {
this._api.playerSetLogDebug(true);
}
if (this._api && this._config.debug) {
this._api.playerSetLogDebug2(true);
}
this._apiLoadResolve();
Expand Down Expand Up @@ -147,39 +174,41 @@ class FlashHLSAdapter extends FakeEventTarget {
this._trigger(EventType.ERROR, error);
},
manifest: (duration, levels_) => {
let audioTracks = this._api.getAudioTrackList();
const parsedAudioTracks = [];
if (audioTracks) {
for (let i = 0; i < audioTracks.length; i++) {
const settings = {
id: audioTracks[i].id,
active: audioTracks[i].isDefault,
label: audioTracks[i].title,
language: audioTracks[i].title, //TODO: Get language?!?
if (this._api) {
let audioTracks = this._api.getAudioTrackList();
const parsedAudioTracks = [];
if (audioTracks) {
for (let i = 0; i < audioTracks.length; i++) {
const settings = {
id: audioTracks[i].id,
active: audioTracks[i].isDefault,
label: audioTracks[i].title,
language: audioTracks[i].title, //TODO: Get language?!?
index: i
};
parsedAudioTracks.push(new AudioTrack(settings));
}
}

let videoTracks = [];
for (let i = 0; i < levels_.length; i++) {
// Create video tracks
let settings = {
active: 0 === i,
bandwidth: levels_[i].bitrate,
width: levels_[i].width,
height: levels_[i].height,
language: '',
index: i
};
parsedAudioTracks.push(new AudioTrack(settings));
videoTracks.push(new VideoTrack(settings));
}
if (this._resolveLoad) {
this._resolveLoad({tracks: videoTracks.concat(parsedAudioTracks)});
this._resolveLoad = null;
}
this._trigger(EventType.TRACKS_CHANGED, {tracks: videoTracks.concat(parsedAudioTracks)});
}

let videoTracks = [];
for (let i = 0; i < levels_.length; i++) {
// Create video tracks
let settings = {
active: 0 === i,
bandwidth: levels_[i].bitrate,
width: levels_[i].width,
height: levels_[i].height,
language: '',
index: i
};
videoTracks.push(new VideoTrack(settings));
}
if (this._resolveLoad) {
this._resolveLoad({tracks: videoTracks.concat(parsedAudioTracks)});
this._resolveLoad = null;
}
this._trigger(EventType.TRACKS_CHANGED, {tracks: videoTracks.concat(parsedAudioTracks)});
},
seekState: newState => {
if (this._firstPlay) {
Expand Down Expand Up @@ -227,25 +256,28 @@ class FlashHLSAdapter extends FakeEventTarget {
load(startTime: ?number): Promise<Object> {
this._loadPromise = new Promise(resolve => {
this._resolveLoad = resolve;
if (startTime) {
this._startTime = startTime;
}
this._startTime = this._startTimeAttach || startTime || -1;
this._startTimeAttach = NaN;
this._apiLoadPromise.then(() => {
this._api.load(this._src.url);
if (this._api) {
this._api.load(this._src.url);
}
});
});
return this._loadPromise;
}

play() {
this._apiLoadPromise.then(() => {
if (this._firstPlay) {
this.ended = false;
this._api.play(this._startTime ? this._startTime : -1);
} else {
this._api.resume();
if (this._api) {
if (this._firstPlay) {
this.ended = false;
this._api.play(this._startTime);
} else {
this._api.resume();
}
this._trigger(EventType.PLAY);
}
this._trigger(EventType.PLAY);
});
}

Expand Down Expand Up @@ -287,10 +319,10 @@ class FlashHLSAdapter extends FakeEventTarget {
}

selectVideoTrack(videoTrack: VideoTrack): void {
if (this.isABR()) {
this._trigger(EventType.ABR_MODE_CHANGED, {mode: 'manual'});
}
if (this._api) {
if (this.isABR()) {
this._trigger(EventType.ABR_MODE_CHANGED, {mode: 'manual'});
}
this._api.setCurrentLevel(videoTrack.index);
this._trigger(EventType.VIDEO_TRACK_CHANGED, {selectedVideoTrack: videoTrack});
}
Expand Down Expand Up @@ -335,6 +367,53 @@ class FlashHLSAdapter extends FakeEventTarget {
this.duration = null;
this.buffer = null;
this.watched = null;
this._startTimeAttach = NaN;
this._lastTimeDetach = NaN;
}

/**
* attach media - return the media source to handle the video tag
* @public
* @returns {void}
*/
attachMediaSource(): void {
this.attach();
this._startTimeAttach = this._lastTimeDetach;
this._lastTimeDetach = NaN;
}
/**
* detach media - will remove the media source from handling the video
* @public
* @returns {void}
*/
detachMediaSource(): void {
const currentTime = this.currentTime;
this.destroy();
this._lastTimeDetach = currentTime;
this._firstPlay = true;
this._loadPromise = null;
}

/**
* Set a source.
* @param {string} source - Source to set.
* @public
* @returns {void}
*/
set src(source: string): void {
this._src.url = source;
}

/**
* Get the source url.
* @returns {string} - The source url.
* @public
*/
get src(): string {
if (this._loadPromise && this._src.url) {
return this._src.url;
}
return '';
}
}

Expand Down

0 comments on commit ba59a7e

Please sign in to comment.