Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add flash engine #2

Merged
merged 12 commits into from
Aug 2, 2018
Merged

feat: add flash engine #2

merged 12 commits into from
Aug 2, 2018

Conversation

itaykinnrot
Copy link
Contributor

No description provided.

itay.kinnrot added 2 commits June 25, 2018 11:32
@itaykinnrot
Copy link
Contributor Author

@OrenMe @dan-ziv @yairans @odedhutzler - lets use this pull for review - i'll update it to master after it. thanks!

Copy link
Contributor

@OrenMe OrenMe left a comment

Choose a reason for hiding this comment

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

In general - I think many comments would have been resolved if the adapter would have implemented base-media-source-adapter.
I can see the exception that it expects HTMLVideoELement, but we could have easily handle this(I think) and this will enforce more alignment between our owned adapters and engines.
My main concern here is maintainability - all the small variations between this and HTML5 engine/adapters may lead to bug fixing or feature implementing to be more hard.

src/flash.js Outdated
this._eventManager.listen(this._api, EventType.TRACKS_CHANGED, (event: FakeEvent) =>{ this.dispatchEvent(event)});
this._eventManager.listen(this._api, EventType.ERROR, (event: FakeEvent) => this.dispatchEvent(event));
this._eventManager.listen(this._api, EventType.PLAYING, (event: FakeEvent) => this.dispatchEvent(event));
this._eventManager.listen(this._api, EventType.TIME_UPDATE, (event: FakeEvent) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be managed in adapter and exposed on API of adapter

src/flash.js Outdated
}
this._currentTime = event.payload.position;
this._duration = event.payload.duration;
this._buffer = event.payload.buffer;
Copy link
Contributor

Choose a reason for hiding this comment

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

buffer and watch which feed the data for seekable and played API - they should hold the actual data and create additional entries in the TimeRanges object returned from them.
For example, watching a video and then seeking while it is played will cause the seekable and played APIs to return an array with several timeRange entries.
The possible solution is on seek events to see if seek target is not in range already and if so add new timeRange entry for played, buffered and seekable
All of the above should be done in the adapter somehow.
I would also create a class for timeRange and timeRanges to manage this

src/flash.js Outdated
this._duration = event.payload.duration;
this._buffer = event.payload.buffer;
this._watched = event.payload.watched;
this._paused = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

better just have the value of this be saved in the adapter and have the engine fo something like return this._api.paused' on the API call for paused`

  get paused(): boolean {
    return this._api.paused;
  }

also, this way you don't have to manage the source of truth in many places

src/flash.js Outdated
});
this._eventManager.listen(this._api, EventType.SEEKED, (event: FakeEvent) =>{
this.dispatchEvent(event);
this._seeking = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

same here - maybe better do it in adapter

src/flash.js Outdated
});
this._eventManager.listen(this._api, EventType.ENDED, (event: FakeEvent) =>{
this.dispatchEvent(event);
this._ended = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

same here - maybe better do it in adapter

* @returns {TimeRanges} - First buffered range (part) of the video in seconds.
* @public
*/
get buffered(): any {
Copy link
Contributor

Choose a reason for hiding this comment

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

return TimeRanges

this._config.flashvars= {};
}
this._config.flashvars.callback = 'flashlsCallback';
this._el.innerHTML = FlashHLSAdapter.getFlashCode(this._config.swfUrl || 'https://cdnapisec.kaltura.com/html5/static/flashhls/v0.4.4.24/flashlsChromeless.swf?inline=1',this._config.flashvars,this._config.params,this._config.attributes)
Copy link
Contributor

Choose a reason for hiding this comment

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

set the default in a default config object and merge in the constructor on init

src/flash.js Outdated

_init(source: PKMediaSourceObject, config: Object): void {
this._eventManager = new EventManager();
this._flashConfig = Utils.Object.getPropertyPath(config, "playback.options.flash");
Copy link
Contributor

Choose a reason for hiding this comment

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

playback.options.* is mainly meant for 3rd party usage - engines should opt to use the defined config object of the player - and AFAICS you pass it as is to adapter so preferably you relate to this object only in the adapter part.

src/flash.js Outdated
*/
enableAdaptiveBitrate(): void {
if (this._api) {
this._api.selectVideoTrack({index: -1});
Copy link
Contributor

Choose a reason for hiding this comment

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

use only the defined object, you can't actually(although it's javascript, you can) pass this - the API should only accept typed object, in this case VideoTrack.
Do what hls and dash adapters do, expose a method for setting adaptive mode, e.g. enableAdaptiveBitrate and in it call the native FLASH implementation which dictates setting -1


getVideoTrack(): ?number {
if (this._api){
return this._api.getAutoLevelCapping();
Copy link
Contributor

Choose a reason for hiding this comment

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

sounds like this is incorrect? getVideoTrack--> getAutoLevelCapping

src/flash.js Outdated
* @public
* @static
*/
static canPlaySource(source: PKMediaSourceObject, preferNative: boolean): boolean {
Copy link
Contributor

Choose a reason for hiding this comment

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

preferNative unused

src/flash.js Outdated
* @public
*/
get currentTime(): number {
return this._api.currentTime ? this._api.currentTime : 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

add if (this._api)

src/flash.js Outdated
let duration: number = 0;
if (this._api.duration) {
duration = this._api.duration;
} else if (this._api) {
Copy link
Contributor

Choose a reason for hiding this comment

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

the sequence here doesn't make sense. if (this._api) should be before if (this._api.duration)

src/flash.js Outdated
* @public
*/
get paused(): boolean {
return this._api.paused;
Copy link
Contributor

Choose a reason for hiding this comment

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

add if (this._api)

src/flash.js Outdated
* @public
*/
get seeking(): boolean {
return this._api.seeking;
Copy link
Contributor

Choose a reason for hiding this comment

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

add if (this._api)

* @public
*/
get played(): any {
return {
Copy link
Contributor

Choose a reason for hiding this comment

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

add if (this._api)

src/flash.js Outdated
}
return {
length: 1, start: () => {
return this._api.currentTime - backBufferLength;
Copy link
Contributor

Choose a reason for hiding this comment

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

add if (this._api) (actually this is flow's job. so just run it....)

src/flash.js Outdated
this._volumeBeforeMute = this.volume;
this.volume = 0;
} else {
if (this._volumeBeforeMute) {
Copy link
Contributor

Choose a reason for hiding this comment

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

could be 0 so check typeof this._volumeBeforeMute === 'number'

* @returns {void}
*/
static runCapability(): void {
let version = '0,0,0';
Copy link
Contributor

Choose a reason for hiding this comment

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

use const (in the whole pull where applicable)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But i'm changing the version...


let flashlsEvents = {
ready:() => {
this._api = new FlashAPI(this._el.firstElementChild);
Copy link
Contributor

Choose a reason for hiding this comment

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

where the event here?

src/index.js Outdated

Flash.runCapabilities();
Flash.getCapabilities().then(((capabilites) =>{
if (capabilites["flash"].isSupported) {
Copy link
Contributor

Choose a reason for hiding this comment

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

use Flash.id

src/flash.js Outdated
@@ -0,0 +1,575 @@
// @flow
import {EventManager, EventType, FakeEvent, FakeEventTarget, ICapability, IEngine} from 'playkit-js';
import * as JsLogger from 'js-logger';
Copy link
Contributor

Choose a reason for hiding this comment

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

import from playkit-js in the line above


isABR(): boolean {
if (this._api) {
return this._api.getAutoLevelCapping() == -1;
Copy link
Contributor

Choose a reason for hiding this comment

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


setABR(): void {
if (this._api) {
this._api.playerSetAutoLevelCapping(-1);
Copy link
Contributor

Choose a reason for hiding this comment

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


selectVideoTrack(videoTrack: VideoTrack): void {
if (this._api) {
this._api.playerSetAutoLevelCapping(videoTrack.index);
Copy link
Contributor

Choose a reason for hiding this comment

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

See hlsjs adapter, which has similar API:

https://github.com/kaltura/playkit-js-hls/blob/44905ee6bbad904aaa8c6a3ba42659d7e67b4681/src/hls-adapter.js#L504-L511

  selectVideoTrack(videoTrack: VideoTrack): void {
    if (this._api) {
      if (this.isABR()) {
        this._trigger(EventType.ABR_MODE_CHANGED, {mode: 'manual'});
      }
      hls.currentlevel = videoTrack.index;
    }
  }

see more here: https://github.com/mangui/flashls/blob/dev/API.md#hlscurrentlevel

I think in current implementation you throw the ABR_MODE_CHANGED event every time.

* @returns {Promise<Object>} - The loaded data
*/
load(startTime: ?number): Promise<Object> {
if (!this._api) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@itaykinnrot , how can this._api not be set?
You have a protection in playkit player.js to not enable accessing engine if it's not selected, and the attach method is simple DOM operation which most likely won't fail.
The load should be a promise over the ready event that is available in https://github.com/kaltura/playkit-js-flash/pull/2/files#diff-934f9a3b93099594e3708f315667203fR103

src/flash.js Outdated
* @returns {void}
*/
play(): void {
if (!this._loadPromise) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@itaykinnrot did you check this?

src/flash.js Outdated
@@ -127,6 +129,9 @@ class Flash extends FakeEventTarget implements IEngine {
this._init(source, config);
}

hideTextTrack(): void {
Copy link
Contributor

Choose a reason for hiding this comment

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

this is in the flow typings - didn't it alert you on missing interface?

@OrenMe OrenMe merged commit 3ec15c7 into review-branch Aug 2, 2018
@OrenMe OrenMe deleted the flash-code branch August 2, 2018 06:47
itaykinnrot pushed a commit that referenced this pull request Aug 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants