r/javascript • u/[deleted] • Jun 22 '16
Those return values though
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType57
Jun 22 '16
It would be great for all javascript to be like this. It would make us slow down a bit and chill as a society.
console.log(new Date()) // "one of these days"
console.log(arr.length) // "a few"0
Jun 22 '16
[deleted]
25
Jun 22 '16 edited Jun 22 '16
falsy statements have a random chance to be evaluated as truthy. A
whateverevent is fired.2
23
u/notunlikethewaves Jun 22 '16
Stringly-typed is best-typed.
4
u/TheNosferatu Jun 22 '16
We already have languages where everything is an object,
Time for a language where everything is a string.
17
u/notunlikethewaves Jun 22 '16
Time for a language where everything is a string.
bash?
4
-2
6
u/TallSkinny Jun 22 '16
I haven't worked with video much, but, is it actually useful is it to distinguish between "maybe" and "probably"? I feel like you'd want to try to play it in either case, and if it fails, you should be handling that gracefully anyways. "Maybe" and "yes" I could potentially see handling differently, but even then I'd probably still try.
13
u/Shaper_pmp Jun 22 '16
is it actually useful is it to distinguish between "maybe" and "probably"
From a UX perspective, yeah, "probably". :-D
More seriously, the problem here is that media containers/codecs/streaming is fundamentally broken in that a computer can't possibly know whether it can play a given stream or file until it tries, and catches any errors that occur.
Given that fundamental gap in functionality, "definitely not" (""), "maybe" and "probably" are the best the browser can do. Certainly it's better than reporting true/false/null, that naive devs may take as gospel but which may be highly inaccurate for many users.
4
u/blood_bender Jun 22 '16
Well,
.play()does return a promise which will be rejected if it fails for any reason, so you're right.But it's a usability type of thing. If the result is
maybe, you probably want to display a warning saying "This media may not work on your device" or whatever. But in the simpler case as you're suggesting, just check for truthynessif (m.canPlayType()).2
u/hufman Jun 22 '16
Well,
.play()does return a promiseExcept on iOS Safari ;)
-1
u/TheNosferatu Jun 22 '16
Wait, people use that?
9
u/hufman Jun 22 '16
As far as I know, every browser on iPhone and iPad is required to use Apple's native javascript engine. This means that every iPhone and iPad user must be treated specially, needing to check the return of .play before using it as a promise.
:/ Just got bit by this.
5
6
Jun 22 '16
shrug At least they document their return values.
API docs that make no mention of possible exceptions or return values are one of my pet peeves.
5
u/Semperdark Jun 23 '16
Can you imagine if they didn't document it, and you got a "probably" from something you were expecting to be boolean? I think I'd just quit programming.
4
u/dtfinch Jun 22 '16
It could be handy to notice that "probably">"maybe", so you can pick the type that has the greatest return value.
2
u/ishouldrlybeworking Jun 22 '16
What kind of actions would an application take if it got back 'maybe' vs 'probably'? It seems like in either case the application would attempt to play the media so the distinction is useless. It may as well be refactored to .cannotPlayType() which returns true if media is definitely unplayable, false otherwise.
3
u/NavarrB Jun 22 '16
I assume choosing which media to attempt to play.
You might have a list of media types available and choose whichever "probably" over a "maybe"
2
1
1
1
0
u/jrwren Jun 22 '16
I'm pretty sure its a Bjork reference: https://www.youtube.com/watch?v=tE11_5Spq1I&spfreload=10&ab_channel=RalphMulucUak
-11
Jun 22 '16
So ... okay ... when did the Mozilla developers lost their minds?
14
u/protestor Jun 22 '16
The issue is that sometimes all you got is a mime-type, which isn't enough to decide whether something is playable. That is, unless you attempt to play.
Example: the mime-type
video/mp4doesn't say what are the codecs inside this mp4, so you get a "maybe". But if you get a more descriptive string likevideo/mp4; codecs="avc1.42E01E, mp4a.40.2", you will get a "probably" (if the browser supports playing H.264 and AAC, that is)Well why "probably" instead of "yes"? Well here the browser is just being honest. The user may have installed a buggy GPU driver or something.
Now, returning an empty string instead of null is inexcusable.
12
u/mmmicahhh Jun 22 '16
Inexcusable? Why would
nullbe a better choice here?
A semantic refusal would be
false(responding to the can play question in the function name)Both
nullandfalsewould introduce situations where a function returns different types at different points, which is even worse than the current solution.4
u/Tiquortoo Jun 22 '16
probably now allows for a future value of yes, if that certainty can ever be achieved, without breaking everything.
4
u/kovensky Jun 22 '16
Even things unrelated to buggy GPU drivers. For example, older hardware decoders would accept H.264 High Profile Level 4.1 (the maximum that a BD was allowed to use, at least back then), but would refuse Level 5.0 streams, even if the stream itself stayed within Level 4.1 limits.
Thus, unless you have a really detailed MIME type that includes even the H.264 header in it, you can't tell if your decoder would accept it until you try it.
-1
u/PlNG Jun 22 '16
True, Undefined, False.
Why deviate from that for fucks sakes.
6
u/Shaper_pmp Jun 22 '16 edited Jun 22 '16
Because you can't possibly know if the computer can play every file based just on the mimetype (hell, even specifying the codec isn't always perfectly reliable). A lot of the time you just have to try and play and see if an error occurs. This is a flaw in the mimetype header/media playing in general, not in the browser or JS API.
Given that it's impossible to ever know for sure whether a particular URL can be played ahead of time, returning
trueis incredibly misleading, and more or less guarantees naive devs will fall over it all the time, leading to unreliable or broken code, errors in production, etc, etc, etc.At least if they look up the API details and see it returns
"maybe"/"probably"that's a really big hint that there's a huge unknown in play, and they should investigate further to ensure they understand the issues involved.0
5
u/lachlanhunt Jun 22 '16
It's actually intentional because the empty string if falsey, and the other two, "probably" and "maybe" are truthy. It was done like that because a naive check using
if (video.canPlayType("video/mp4"))will type cast in a sensible way, while allowing the more specific values to be checked for more granular control when selecting the media type to play. It just expresses the confidence level in being able to play a certain type of media based on the content type, which is as reliable as possible before inspecting the actual file to see what's in it.2
u/vinnl Jun 22 '16
It's not Mozilla, it's what WHATWG (or the W3C?). And they're limited by Javascript although usually, numbers are used instead of strings to compensate for the lack of enums or something else.
2
u/Shaper_pmp Jun 22 '16
This is nonsense. The problem is that with the wide variety of codecs and container types it's often impossible to know if a given browser can play a given file without actually requesting it and trying, so all this API call can do is give a best-guess (hence the weird return types to make that abundantly clear to the developer using it).
It's true that JS doesn't have enums, but that's a distinctly side-issue, and it could be easily worked around by defining
HTMLMediaElement.PROBABLY = 1; HTMLMediaElement.MAYBE = 2;, etc. JS devs do this all the time to avoid magic numbers in their code.The problem is that
1doesn't scream "you can't rely on the result of this query" every time you look at the code, whereas"probably"is almost impossible to miss.1
u/vinnl Jun 22 '16
Yeah it's pretty logical that they're using strings, I was merely pointing out that "weird" return types happen far more often.
Using properties wouldn't be that good of a solution, as they can be overwritten. Since last year, though, symbols could've been an option.
0
u/jijilento Jun 22 '16
Yea, large parts of the webaudio api operate on magic numbers so like 4 would represent playable in a method (I don't have the documentation in front of me). I'm not sure why they couldn't polyfill enums for these complex returns.
0
-5
u/delventhalz Jun 22 '16
'probably' and 'maybe' mean the same thing to my ear. Something like 'likely' and 'possibly' might have drawn a better distinction. The empty string makes sense though. I love me some falsey values.
12
u/Fs0i Jun 22 '16
Probably denotes that it's more likely than not (probability > 50%), "maybe" just says probability > 0%.
-2
u/delventhalz Jun 22 '16
Sure. Just saying there are different words that would make the semantic distinction more clear. In life, I would say "probably" and "maybe" in similar circumstances, even though they mean different things.
0
Jun 22 '16
[deleted]
6
u/inu-no-policemen Jun 22 '16
What you actually want there is an enum, but JavaScript doesn't support those.
TypeScript and Dart do have enums. TypeScript even has string types for exactly this kind of situation.
6
u/Fs0i Jun 22 '16
Yep. This function has the return-type
"maybe" | "probably" | ""in TypeScript. Super helpful :)
97
u/saadq_ Jun 22 '16
Wish they had used something like
"lolnope"instead for that case.