In my Media API attempt, I’m currently using a Task to set the currentTime property of an audio or video node. Since I can set properties with VirtualDom, this drives me nuts as an unnecessary use of native code.
However, I have a problem with setting the property using VirtualDom.property, so I’m reaching out here to see if anyone has a decent solution.
Here’s what I can do:
audio [src="music.mp3", currentTime=15][]
And that will work fine…as long as the currentTime property is set to a different number each time. So if I have a “jump 15 seconds ahead button” that just adds 15 seconds, I’m probably fine. There might be a 1 in a billion occasion where it doesn’t work, because the numbers line up just right, but I can live with that.
But what if instead of setting the currentTime relative to my current playhead position, I want to set it to a specific time? The most obvious is a player that simply has a restart button, that sets currentTime to 0. The first time someone clicks this button, it will work. But the second time, it won’t, because the virtualDom riffing algorithm doesn’t detect a change in the property.
A lot of this is because an audio or video player has side effects…currentTime does change. And maybe that makes it a side effect that should be properly done through a task, but there’s a lot of smart people on here and maybe someone has a solution.
Then you could force the virtual Dom to re-render by giving it a different key each time. Although it would actually remove the node and create a new one. I’m not sure if that has any undesirable side effects.
(By the way there’s a slight typo in the code snippet. Elm syntax doesn’t have those equals signs. )
I haven’t tested, but I’m fairly certain that will have an undesirable side effect: if we’re talking about an audio tag, the audio file will reload on some (or all) browsers.
Drat!
The only other thing that comes to mind is adding some tiny random number to the time. Say a few microseconds or even nanoseconds. So small that it’s irrelevant to the media, but enough so the virtual Dom algorithm doesn’t see it as exactly identical. It’s a bit of a hack, but might be good enough depending on your requirements and preferences!
What about the reverse? Setting the currentTime to the actual current time, then to the time that you want to seek to? Not sure whether that would cause any unintended side-effects either.
@mcordova47 It was my first attempt many months ago. “timeupdate” is only called 4 times a second on some browsers, and almost none of them are frequent enough. As a result, it leads to stuttering playback.
@pateh setting currentTime for an offset isn’t really the problem (except on a one in a billion chance that the time you’re trying to set is the same), it’s what happens when you want to set an absolute time, that’s already been set immediately before.
If I set currentTime = 15, the. 20 seconds later want to set it to currentTime = 15, with no other changes in the middle, nothing will happen.
It’s lets common than changing time relative to the current position, but it does have real world uses, such as restarting, or a chapter list.
It’s a tough problem. Unless someone has some wacky other solution, I’m just going to chalk it up to currentTime being a side effect of a media player (since it controls its own state, mostly) and so needs to continue to be treated as a task.
@mattpiz yeah just like that!
Doing it this way doesn’t feel at all as hacky as I’d imagined it might be!
The equality check is a clever addition. It removes the need for using random numbers and having potential clashes, which is what I was thinking of as the “hacky” bit.
I think this is probably a better path. An Html value is not intended to have side effects like playing music. It is some data that should change the display and maybe give messages through normal on events.
I think the “maybe that makes it a side effect” suggests that there is some confusion about what is and is not an effect. Is that the root issue here? Because I think seeking through music that is playing is definitely an effect.
More broadly, if I thought about “playing sounds” in isolation from the browser, there is no way the API I would come up with was DOM manipulation. So I’m not sure this is a great direction overall for the root problem.
This was the conclusion I came to when first thinking about an API around it and that I implemented in my Media API proposal. Going to leave as is.
But since it’s technically a property, I second guessed myself and so reached out to put better minds than mine to work on it (and a number of really smart responses ensued). One thing I really like about elm: instincts and what feels right often matters, and getting too much in your head can ruin things. Coming from a creative background, this is what makes it a great creative tool. Thanks, Evan.