Keep audio playing

Hi,

I wish to keep some audio playing between page navigations as demo’d in this video: Ruby on Rails #143 Turbo Permanent: persist Audio Video | SupeRails

I have an audio tag on page 1 of my app like so:

                <audio controls preload="none" id="<%= dom_id(@park, :soundtrack)%>" data-turbo-permanent>
                    <source src="<%= @park.soundtrack1.url %>" type="audio/mpeg">
                </audio>

Then a similar audio tag on page 2:

                <audio controls preload="none" class="object-title-bar__soundtrack" id="<%= dom_id(item, :soundtrack)%>">
                    <source src="<%= item.soundtrack1.url %>" type="audio/mpeg">
                </audio>

The resulting audio elements have identical id’s but the audio stops when navigating. Any idea why?

I will say that the page structure is different but it’s the same type of element with the same id and referencing an identical audio file. The only other difference i can see is that the first audio element is inside a turbo-frame, but the link to the second page has target="_top" on it. Would that be the issue? and if so is there a way to make it work but keep the link working the same way?

Any ideas?

Anyone able to help me out here?

Hey, I just tested out this use case locally and I think I discovered the issue.

Both elements must have the same id and also the data-turbo-permanent attribute otherwise it will not work.

If you have on one page the id=“persisted-audio” and data-turbo-permanent but on the other page you only had the id and no data-turbo-permanent it will not persist.

Hmmm,

I just tried that. I added data-turbo-permanent to the audio element on the second page. When i go to the first page, start playing the audio, and clikc the link to the second page, the audio player doesn’t show up? It’s not even in the DOM? If I then refresh the second page it shows up again.

Any ideas?

No idea about that, try debugging and make sure the elements are actually the same and they both exist on the page and are not lazy loaded or anything like that

I tried the same use case with your same exact code but instead of dom_id, I used a static id of “audio” and a src of a tmp file. And it worked fine when navigating. Another thing is if you are using target: “_top” to break out of a frame it will not respect data-turbo-permanent elements because that uses the standard browser refresh. If you need to change this then change the link from using target: “_top” to data-turbo-frame=“_top”

I didn’t realise about target=“_top”. I’ve changed this now but it still doesn’t work.

I also tried wrapping the audio element in a div with the id and data-turbo-permanent on but still no luck.

Oddly, the element vanishes on the second page when i click the link on the first page.

On the second page, in the dom where the element should be is just:

<meta name="turbo-permanent-placeholder" content="soundtrack_park_32694">

Not too sure why that shows but the element doesn’t?

1 Like

I think i’ve resolved it!

I think the CSS View Transitions are causing the issue.

I have this to enable view transitions:

addEventListener("turbo:before-render", (event) => {
  if (document.startViewTransition) {
    const originalRender = event.detail.render
    event.detail.render = (currentElement, newElement) => {
      document.startViewTransition(()=> originalRender(currentElement, newElement))
    }
  }
})

addEventListener("turbo:before-frame-render", (event) => {
  if (document.startViewTransition) {
    const originalRender = event.detail.render
    event.detail.render = (currentElement, newElement) => {
      document.startViewTransition(()=> originalRender(currentElement, newElement))
    }
  }
})

Commenting this out causes the audio player to work perfectly. Weird eh?

1 Like