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

Could use a good way to get the current tech name #1234

Closed
dominic-p opened this issue May 23, 2014 · 23 comments
Closed

Could use a good way to get the current tech name #1234

dominic-p opened this issue May 23, 2014 · 23 comments
Labels
enhancement needs: more info Please make enough detailed information is added to be actionable.

Comments

@dominic-p
Copy link
Contributor

It would be nice if there was a reliable way to get the current tech. It could be as simple as exporting player.techName, and I could throw together a pull request, if that would help.

This came up when working on the Google Analytics plugin. See the issue here.

@heff
Copy link
Member

heff commented May 23, 2014

I push back on exposing tech info/access because it enforces the core video.js philosophy that techs should all work the same, and plugins shouldn’t make conditional decisions based on what tech is loaded. Usually when someone wants direct access to the tech it's because we've missed something in making a tech work the same, or we're not exposing some other specific piece of data that's needed at the player level.

Can we expand on this specific use case here? What's the original reason for accessing the tech?

@dominic-p
Copy link
Contributor Author

@heff, that's a good point. My use case is analytics. It would be nice to know what techs people are using for support purposes. Of course, you can deduce some of that information from your browser stats, but direct access seems like it would be more useful.

Without a sanctioned way to access the tech, we wind up with a workaround like the one in the issue I referenced above. Probably not ideal.

@heff
Copy link
Member

heff commented May 23, 2014

That's funny because we had almost the exact same use case come up at Brigthcove for internal support info. Just knowing which tech was loaded when an error occurred.

If you knew what techs people were using, what would you do with that info? Basically how does it become an actionable metric?

I've never felt a strong need for that specific info myself because you can usually tell from what browser is used, and almost definitely from the browser/source combination.

IE8: Flash
Firefox Mac: html5 if you provide a webm/ogg, Flash otherwise. That is until FF supports mp4 on macs, which I think is soon?
Everything else: html5.

That works for the core techs at least. Does that fall down at all in your use case?

@gkatsev
Copy link
Member

gkatsev commented May 24, 2014

Firefox Mac: html5 if you provide a webm/ogg, Flash otherwise. That is until FF supports mp4 on macs, which I think is soon?

Newest versions of firefox on OSX should have mp4/h264 support in html5 now. However, that's only if the hardware and OS support h264 natively: https://developer.mozilla.org/en-US/docs/HTML/Supported_media_formats#MP4_H.264_(AAC_or_MP3)
@heff so, if you're still seeing flash in firefox, it's possible that your OSX laptop is too old or something.

@dominic-p
Copy link
Contributor Author

You can definitely piece together a picture from browser/source, but this would save you a step. Also, in the link posted by @gkatsev, it seems like H.264 support on Firefox is dependent on platform. So, I can't really assume that just because a visitor is using a modern Firefox he is getting HTML5 video (if my only source is H.264).

In general, it would be nice for me to know "at a glance" what portion of my visitors are winding up with flash.

@mickey
Copy link

mickey commented Jun 2, 2014

I have the same use case as @dominic-p; analytics and support, also I'm the maintainer of videojs-ga.
I understand your concern about exposing the tech being used.
Without exposing it, do you think something along these lines would work:

function whichTech() {
  for(var i = 0; i < videojs.options.techOrder.length; i++) {
    var tech = videojs.options.techOrder[i];
    var techName = tech.charAt(0).toUpperCase() + tech.slice(1); // videojs has a capitalize function but I'm not sure it's exposed

    if (videojs[techName].isSupported())
      return(techName)
  }
}

@gkatsev
Copy link
Member

gkatsev commented Jun 2, 2014

@mickey that function will give you back the first supported tech, which might not be the currently loaded tech, though, hopefully it is, since the first supported tech is the one that should be used.
Perhaps, if you do player.options().techOrder instead you might get slightly more reliable info if the user used a different techOrder.

@mickey
Copy link

mickey commented Jun 2, 2014

@gkatsev Thanks for your reply!
Sorry if it doesn't make sense, I'm still trying to navigate videojs' internals. I've changed the function according to your feedback:

function whichTech(player) {
  for(var i = 0; i < player.options().techOrder.length; i++) {
    var tech = player.options().techOrder[i];
    var techName = tech.charAt(0).toUpperCase() + tech.slice(1);

    if (videojs[techName].isSupported()) {
      return(techName);
    }
  }
}

I guess for being more reliable I would also need to test with canPlaySource but I cannot find a way to get the current source/type being played. currentSrc only returns the url not the type.
Something like:

function whichTech(player) {
  for(var i = 0; i < player.options().techOrder.length; i++) {
    var tech = player.options().techOrder[i];
    var techName = tech.charAt(0).toUpperCase() + tech.slice(1);

    if (videojs[techName].isSupported()) {
      if (videojs[techName].canPlaySource(player.GETSOURCEANDTYPE()))
        return(techName);
    }
  }
}

@dominic-p
Copy link
Contributor Author

@mickey, that's a nice solution, but it could run into problems. As @gkatsev said, it will only tell you the first supported tech.

For example, in my deployment I define a blanket techOrder that looks like this ['html5','flash','youtube']. Then, if I'm on a modern browser, but I only have a youtube URL to use as a source, the tech will be youtube, but your whichTech function would return html5 because that's the first supported tech.

Maybe that's an edge case, but it would be preferable for me to get the actual running tech straight from the video.js API if possible.

@gkatsev
Copy link
Member

gkatsev commented Jun 2, 2014

I think the most reliable way currently is to get the vjs-tech element and inspect it. html has a class of vjs-html5-tech, flash has a class of vjs-flash-tech or something along those lines. However, yes, perhaps just exposing techName is needed.

We could augment whichTech to be cleverer and take the currentSrc into account, which I think is what @mickey tried to do in the second example.

@mmcc
Copy link
Member

mmcc commented Jun 13, 2014

Looking at the dom, I think what @gkatsev is referring to is the tech ID that gets set.

The vjs-tech class gets the following IDs set:

  • For HTML5: YOUR_VIDEO_ID_html5_api
  • For Flash: YOUR_VIDEO_ID_flash_api

@heff
Copy link
Member

heff commented Jun 13, 2014

Yeah, you could essentially either recreate the video.js source selection process, or look for something like _([^_]+)_api.

I can definitely understand that it would be interesting to see the stats between the two. I still can't think of a way that would be specifically helpful in making additional decisions or strategies. Between the methods mentioned here for finding it, and using source + platform data to see similar stats, there's definitely some alternative options here.

I still think enforcing the video.js philosophy is strong enough reason to keep it obscured. Obviously advanced users like everyone on this thread can still figure it out, and I don't have any problem with that, but for the average user I think it's still valuable to keep that safety in there.

I'm going to close this issue for now, but feel free to keep discussing methods for getting the info, or other reasons for exposing it.

@heff heff closed this as completed Jun 13, 2014
@dominic-p
Copy link
Contributor Author

I can understand the reasoning here. Sniffing the DOM is what I was trying to avoid by opening this issue, but it's probably going to be the best solution. Thanks for the consideration.

@dominic-p
Copy link
Contributor Author

I just ran into another use case for this. In my resolution selector plugin, we're discussing enabling support for the flash tech. Right now, I use a pretty hacky solution to only enable the plugin for HTML5. If we bring flash online, we're right back to sniffing the DOM to decide if the player is using flash or HTML5 or another tech. With this in mind, I'll just layout one more time why I feel it would be good to have this available.

I don't like trying to figure out the tech from the DOM because it creates a maintenance problem. When we decide we like hyphens instead of underscores for class names, the regex for extracting the tech will break. When we decide the _api suffix isn't necessary, the regex will break again. When, someone writes a 3rd party tech plugin and forgets to include the VIDEO_ID_{techname}_api class we won't be able to detect the tech used. Sure these are minor issues, but they make maintenance a pain.

I completely agree with the philosophical reasons behind not wanting to expose this info. It shouldn't matter to the end user or the website owner who wants to play videos on his site what tech is being used. But, for plugin developers, this information is valuable. So, there are draw backs either way. If we expose the techName we run the risk of people using it foolishly. If we don't, we leave plugin developers to try hacky workarounds.

Ok, I've said my peace, and I'll try not to bring it up again. :)

@heff
Copy link
Member

heff commented Jun 27, 2014

Cool, this is good example. When switching resolutions, what's happening that's interacting directly with the tech?

@dominic-p
Copy link
Contributor Author

Thanks, and that's a good questions. To be honest, flash is not my strong suit. But, from what I understand, we won't be able to simply issue a player.currentTime( x ) call if we're using the flash tech. It seems like we'll need to include a query string var at the very least to tell the server where to start the (pseudo)stream. You can checkout the discussion here.

Maybe it should be up to video.js to make sure that player.currentTime( x ) just works with whatever tech is being used?

Even still, I will want to disable the plugin on unsupported 3rd party techs. For example, the YouTube tech plugin implements its own resolution selector. I shouldn't enable my plugin for that tech, but right now I have no good way of knowing for sure which tech is being used.

@heff
Copy link
Member

heff commented Jun 27, 2014

Ah yeah, that makes sense. Flash can't jump straight to a time when it loads without pseudo streaming, and we don't have pseudo streaming built in to the flash player. I think there's two ways I could see approaching this specific issue.

For this we might define a tech feature key that is something like "features.currentTimeAtLoad" or more likely "features.mediaFragments", which is the most closely related html API.

I think the whole tech feature concept needs some more thought, since it was kind of hacked in there. And also I don't think it's exposed to plugins yet. But I do think that's the right direction. I like that it doesn't require plugin authors to keep track of what techs support what features.

@dominic-p
Copy link
Contributor Author

"Tech features" definitely seems like a good approach to this sort of thing. One potential pitfall I see is that it might be difficult to determine exactly what is supported. For example, the flash tech would support the theoretical currentTimeAtLoad feature on an RTMP source, but not on a regular source unless the server is configured for pseudo streaming. How could it know what to report for this feature?

Also, in my particular use case, I would assume that the YouTube tech would likely support that feature, but I still wouldn't want to enable my plugin for it because it has its own quality selector. I'm back to needed to know the tech name so I can whitelist which techs to enable the plugin on. Maybe that's an edge case, but it's something to think about.

@NekR
Copy link

NekR commented Jan 30, 2015

So what is the problem of not exporting tech info? Will break something? Or you care about few bytes. This strange that everytime when people wants to do some hacks with videojs they need ask you to implement them in videojs itself.

I do not like what videojs uses native fullscreen on android and particularly, in my case, that fullscreen is not useful. So I changed behavior of it to use full-window instead, but I cannot do it with minified version because tech info is not exported.

Can you please remove support of native fullscren on Android Stock Browser?

@NekR
Copy link

NekR commented Jan 30, 2015

player.supportsFullScreen()
video.js:23 VIDEOJS: Video.js: supportsFullScreen method not defined for Html5 playback technology.
TypeError: undefined is not a function {stack: (...), message: "undefined is not a function"}

This also seems nice. One method on player is exported, but same method on tech not.

@heff
Copy link
Member

heff commented Jan 30, 2015

@NekR the problem has already been explained, but in version 5.0 we are moving away from closure compiler (variable mangling) so you will be able to do whatever you want.

You should open a new issue for the fullscreen discussion.

@AlicanC
Copy link

AlicanC commented Apr 9, 2015

Or maybe you could use a bad way to get the current tech name:

var getTech = function getTech(vjsPlayer) {

  for (var key in vjsPlayer) {
    if (vjsPlayer[key] instanceof videojs.MediaTechController) {
      return vjsPlayer[key];
    }
  }

};

var getTechName = function getTechName(vjsPlayer, tech) {

  if (!tech) {
    tech = getTech(vjsPlayer);
  }

  for (var key in videojs) {
    if (typeof videojs[key] === 'function' && (videojs[key].prototype instanceof videojs.MediaTechController)) {
      if (tech instanceof videojs[key]) {
        return key;
      }
    }
  }

};

var a = videojs('mainPlayer');

var tech = getTech(a);
var techName = getTechName(a);

console.log(tech, techName); // [object Object], "Youtube"

@gjutras
Copy link

gjutras commented May 27, 2015

We found another use case. We want to check the flash player version if they're playing flash and show an upgrade warning if they're using flash player prior to 12. I'll be using the examples above to get it. But there is another use case for why. This was the result of a few internal and external helpdesk tickets. (I know the internal helpdesk ticket is a sad one.)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement needs: more info Please make enough detailed information is added to be actionable.
Projects
None yet
Development

No branches or pull requests

8 participants