VirtualDom property setting question

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.

Maybe try using a keyed node?

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.

Maybe we need keyed properties?

@Brian_Carroll, yeah, I tried it out here. It doesn’t work.

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!

That does work. It’s for an api design though so I’m not sure a hack is the best idea.

If you’re ok with a hack, maybe -0 would work?
So you could switch between +0 and -0.
Probably a dumb idea, but would be fun if it worked :wink:

It’s a brilliant idea, but only works for the case of 0, unfortunately. Need something more general purpose.

I have to test, but think I have a solution.

UPDATE: I tried setting the property then removing it once it was seeked, but it didn’t work. It reset to 0 every time. Ellie here

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.

This way seems to work – https://ellie-app.com/83HQnsBHPa1/2

It keeps the current time in the model through on "timeupdate" and uses that to know the offset where we want to set currentTime to.

1 Like

@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.

1 Like

@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.

Like this?

I’ve got another hack, this works without changing the time:
https://ellie-app.com/mGfdRSPhta1/0

e.g. just pass it as a string and add a meaningless space to update

@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.

Nice work :slight_smile:

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.

3 Likes

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.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.