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

Handle the loadstart event at the player level #1194

Closed
heff opened this issue May 5, 2014 · 17 comments
Closed

Handle the loadstart event at the player level #1194

heff opened this issue May 5, 2014 · 17 comments

Comments

@heff
Copy link
Member

heff commented May 5, 2014

The loadstart event is the closest thing to something like a 'srcchange' event defined in the HTML5 spec. It's fired whenever the src is set or the source selection process begins, and is fired even if preload=none.

Currently the player relies on the tech to fire the loadstart event and bubble it up to the player, but this isn't exactly right because, in the scope of the player, that would only happen AFTER the source selection process, when the selected source is handed to the tech. That means if a source isn't selected, the loadstart event won't get fired and we won't know that src change was even attempted.

One place this could have an impact is the error state (the player has an existing error). We should be able to use the loadstart event to clear the error state, and possible other player states (networkState, readyState) if we decide to handle them at the player level.

Another option would be to create a srcchange or contentupdate event that the player fires whenever src() is used. The downside of this is we would be inventing a new event and detracting from how the html5 video element works, which we try to avoid, and could have unforeseen implications down the road.

The most difficult use case to work through so far is the ads use case, and understanding how we need the events to work in the process of switching between content and ad sources behind the scenes.

Also, wrap #1672 into this.
And #2382

IRC CHAT LOG: @dmlap, @heff

dmlap: heff: sorry, had to walk away. I like the "feed it directly to plugins" option but it gets kind of tricky if you consider playlists
dmlap: what is going to keep track of plugins that need metadata and re-initialize them when the src changes?
dmlap: maybe a playlist plugin could do that
dmlap: but the plugins would still have to register in some interesting way, or listen for an event
dmlap: either of which seems equivalent to just listening for loadstart and then querying the player
heff: yeah, that's true. So you like the 'store in options' method too then?
heff: I think the loadstart event is the right one to signal plugins to update their info
dmlap: yeah, that's my preference
dmlap: the only trick is when ads are involved
dmlap: we invented this new event, 'contentupdate' to indicate when src was changed for reasons *unrelated* to ads
dmlap: i wish we could just use loadstart but client side ads hijack the video element on mobile devices to do their business
dmlap: and they may emit multiple loadstarts
dmlap: i'm fine with code like this:
dmlap: player.on(player.ads ? 'contentupdate' : 'loadstart', function() { … })
dmlap: but it's not ideal
heff: yeah, I was thinking of adding a 'srcchange' event for similar reason, but then reading through the spec, the loadstart event happens at the beginning of the source selection process, and is triggered even if preload=none
heff: so my thought is we take loadstart away from the techs and have the player manage triggering it
dmlap: that would require making the player ad-aware. that is an evil road to tread, trust me
heff: it would?
dmlap: well, maybe i'm misunderstanding your proposal
dmlap: i thought you were saying that loadstart would only fire when a non-ad-related src change occurred
dmlap: were you talking about something else?
heff: I guess I'm not exactly sure how ads work. Do they call player.src() to update what's playing?
dmlap: not in the libs i'm familiar with
gkatsev
they may
dmlap: IMA3, for instance, calls video.src directly on the element
dmlap: (so yes, but one level of abstraction down)
heff: so if the player now ignores loadstart events from the video element, what makes it need to be ad aware?
dmlap: hmm
dmlap: that might work. is there a reason you'd want to know about loadstart from ads?
heff: if there was, I could see using a more custom event like ad:loadstart. Don't we do that already with some things?
dmlap: yes, there are custom, ad-related events
heff: I guess there could be issues with the general state of the player, but I can't think of specifics
dmlap: yeah, i'm a little worried we might be "doing too much" in the player
dmlap: and end up mis-representing the underlying video state
dmlap: i guess that's only a problem if devices behave in ways we don't expect
dmlap: but they tend to do that
heff: yeah. I do know I need some event to clear errors and reset player state when you set a new source, I'd like it to be loadstart, and I can't rely on the tech loadstart in that case
dmlap: we could keep thinking on that one
heff: yeah
heff: might be worth a new issue
dmlap: yeah, i think it is
dmlap: worth going over the possibilities at least
dmlap: i'm going to go forward with the metadata-as-options design though
heff: cool
dmlap: if loadstart becomes smarter, that will still be valid and useful
@dmlap
Copy link
Member

dmlap commented May 5, 2014

The video metadata example that triggered this discussion.

@dmlap
Copy link
Member

dmlap commented May 5, 2014

There is at least one philosophical question which needs to be resolved: is video.js intended as a drop-in replacement for a video element or is it a video element++? If it's a drop-in replacement, I would expect to "see" all the loadstarts generated by player interactions, even low-level ones like those generated by ad plugins. If it's a higher-level abstraction, it makes sense to do a lot more event normalization.

@heff
Copy link
Member Author

heff commented May 5, 2014

a drop-in replacement for a video element or is it a video element++?

That's a good question. In my opinion, working with video.js should "look" just like working with the video element. However whether or not video.js is allowed to abstract away something like mid roll ads, so that the API might be unaware of their loading, I'm not exactly sure. I think that would be a tech-level decision, not player-level. e.g. if we wanted to hide ads playback, we might have an HTML5+ads tech. But otherwise techs should expose everything that's going on.

even low-level ones like those generated by ad plugins

I think part of the issue here is that ad plugins really shouldn't be talking directly to techs, and creating low-level events that don't originate from the player API. I don't have all the background on why that's needed though. To a good degree we can maintain state at the player and keep it reliably up to date with the underlying tech, but if plugins start bypassing the player to talk to the techs directly, I think that could mess things up.

@dmlap
Copy link
Member

dmlap commented May 12, 2014

There are a number of mobile devices which can't really handle two video elements at once. To work around that, an ad library may re-use the video element that's used for regular playback. Google's client-side ad implementation, IMA, uses this approach. It's a frustrating complexity but I'm not aware of a better solution on those platforms.

@heff
Copy link
Member Author

heff commented May 13, 2014

What's the limitation of the player API that makes talking directly to the video element needed?

@dmlap
Copy link
Member

dmlap commented May 13, 2014

IMA is written to talk directly to a video element so the attributes-to-methods (e.g. video.src = 'movie.mp4' to video.src('movie.mp4')) conversion in the video.js API leaves IMA looking for functionality in the wrong places. Complicating the situation a bit further, IMA is auto-updated by Google regularly. video.js doesn't cover all of the video spec today so there's a possibility Google could auto-update their plugin to use a new property and break the player.

@dmlap
Copy link
Member

dmlap commented May 13, 2014

One potential disadvantage of the ads-as-a-tech proposal is composability. With ads handled in a plugin, it's pretty easy to imagine how Flash ads work over HTML video, or how HTML ads could be overlayed on top of the YouTube tech. Techs are mutually exclusive today so I'm not sure how we would achieve those sorts of combinations. We could do some sort of tech-state-preservation mechanism but that sounds pretty involved.

@heff
Copy link
Member Author

heff commented May 13, 2014

One potential disadvantage of the ads-as-a-tech proposal is composability

Ah right, that kind of kills the whole benefit of video.js. Shame on me.

So, IMA is an external javascript library that we have no control over, and it expects being handed a video element specifically.

For the sake of exhausting every angle...

  • Is there an underlying API that we could build on ourselves instead of relying on Google's IMA javascript?
  • What if the player could "lend" the video element to a plugin? The player would disconnect all listeners and just wait idle until the plugin returned it. Would that be a potential solution?

But otherwise, just handing the live video element to IMA means the player is no longer in control of it. Which isn't too horrible since the player already doesn't really assume it's in control anyway, but the more we track state at the player level the more potential disconnects it could cause. The disconnects would come from:

  • Us not implementing state tracking correctly
  • Browsers not firing the needed video events correctly enough for us to always know the right current state

I haven't seen any specific issues with the latter yet, but I also haven't tried implementing networkState or readyState to any significant degree.

@heff
Copy link
Member Author

heff commented May 21, 2014

See #863 for a related issue.

@heff
Copy link
Member Author

heff commented Apr 1, 2015

@dmlap I think you have a better understanding of this loadstart issue then I do. How does the new playlists/ads work affect this one?

If we do end up making the player handle loadstart, it'd be good to get it in for 5.0.

@dmlap
Copy link
Member

dmlap commented Apr 2, 2015

Since we filed this one, we decided that contrib-ads should do its best to abstract away the ad-related parts of playback for everyone that isn't interested in hearing about them. Rather than swallow the events entirely, we're prefixing them with "ad" (e.g. adloadstart) to allow people to opt-in to the complexity of mobile ad playback if they really want to.

I think this puts us in a good position to trigger events like loadstart at the player level. It's still going to be difficult to emulate correctly on all platforms but I think it's worth it to make video.js behave in a more spec-compliant way. Definitely a good candidate for 5.

@heff heff added confirmed and removed needs: discussion Needs a broader discussion labels Apr 2, 2015
@heff heff added this to the v5.0.0 milestone Apr 2, 2015
@dmlap dmlap self-assigned this Apr 27, 2015
@dmlap
Copy link
Member

dmlap commented Apr 27, 2015

According to the latest version of the standard, loadstart is the fired at the end of the synchronous section of the resource selection algorithm, after the mode (e.g. src attribute or source element children) has been selected. Conveniently for us, it is also queued to fire before the candidate selection algorithm runs when operating in children mode. I believe we would have standards-compliant behavior if the player was always responsible for emitting loadstart and the tech-level event was always ignored. Loading a new video would look like this:

  1. Call player.src()
  2. The player emits loadstart
  3. Initialize the appropriate tech
  4. Tech runs its own source selection algorithm and emits loadstart
  5. The player ignores the tech loadstart event

@heff
Copy link
Member Author

heff commented Apr 27, 2015

👍

@dmlap
Copy link
Member

dmlap commented Apr 28, 2015

I think this one needs to wait for Techs 2.0 to complete before it can be started.

@heff heff modified the milestones: Techs 2.0, v5.0.0 Apr 30, 2015
@heff
Copy link
Member Author

heff commented May 11, 2015

Wrap #1672 into this one.

@heff heff modified the milestones: v5.0.0, Techs 2.0 Sep 14, 2015
@heff heff removed this from the v5.0.0 milestone Sep 15, 2015
@gkatsev
Copy link
Member

gkatsev commented Jun 11, 2018

So, I think we can close this one for now since we've been living with it as is for now. Also, we recently released the sourceset event (though, under a flag for now) which could help.
Until and if we run into more problems, this can stay closed.

@gkatsev gkatsev closed this as completed Jun 11, 2018
@aneetaanu
Copy link

jQuery(window).ready(function() {

var player = videojs("hls-example-5", {}, function() {});

jQuery('.play-vide-button').click(function() {
   var media = document.getElementById("hls-example-5");

const playPromise = media.play();
if (playPromise !== null){
playPromise.catch(() => { media.play(); })
}
player.pause();
player.src({src: 'tvmedia : '') ?>'})
this.load();

    player.ready(function() {
        console.log("READY")
        this.play()
    });
    this.pause()
    return false;
});

window.onload=function(){
this.play()
}
});

imgpsh_fullsize_anim (4)

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants