Preact: Preact indirectly trigger a video pause

Created on 8 Jul 2017  路  15Comments  路  Source: preactjs/preact

Hi,

I came across a quite intriguing issue that I assume is related to the DOM mutations strategy that preact is using.

When rendering the following component with preact:

class Player extends Component {
    state = { show: true }

    componentDidMount() {
        document.onclick = () => {
            this.setState({ show: false })
        }
    }

    render() {
        return (
            <div>
                { null }
                { this.state.show && <div></div> }
                { null }
                <video
                    autoplay="true"
                    src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
                    style={ {width:'400px',height:'300px'} }
                />
            </div>
        );
    }
}

I observed that on state change (when clicking on the document), the video playback is being paused. After reproducing in a minimal example and comparing with React I can say that this issue is only reproducible with preact.

Here is a repo of a demo showing the issue: https://github.com/happypoulp/preact-video-issue

The structure of the elements in the render function above may seems peculiar but the issue does not seem to exist when using another structure (like removing one of the { null } or changing the

I have no idea about why a change in the DOM may cause a video to be paused but since this issue is reproducible 100% of time, I guess that someone more familiar with the rendering strategy of preact may have a good explanation for it.

I have found various ways to avoid this issue (by changing the structure or by moving out the video tag out of the render function) so it's not really critical but I'd really like to understand what's happening here.

Issue reproduced with preact ^8.1.0, on Chrome 58.0.3029.110.

Thanks.

duplicate has fix

Most helpful comment

@vedam Your issue is actually different from OP's. Preact caches components and their DOM elements, so when the first time video route loads, it works fine; next time it loads, it's the cached element, and "Video pausing on DOM move/unmount is straight Google Chrome bug". I think React doesn't cache components, so every time video loads, it's a new component, and it autoplays fine.

Unfortunately, there is nothing much to do unless we expose one option to disable component caching.

All 15 comments

Hiya! This is actually the same as #705. We merged a fix in #717 and it will be released in 8.2.0.

Nice! Thanks a lot! So what was triggering the issue, was the video tag somehow moved into the DOM which triggered the pause?

Yup, it would have been getting moved within its parent. I'm just working to push 8.2.0 out right now.

8.2.0 is out and should fix this :)

Please let me know and re-open if it's still messed up for you.

@developit Unfortunately I just updated and the issue is still reproducible with preact 8.2.0. You can reproduce it here https://github.com/happypoulp/preact-video-issue.

  • Sorry for what's about to follow *

I JUST SPENT ALL AFTERNOON FIGURING OUT WHY THE VIDEO PAUSED. aogsenwlq;kregj

I then came here. Saw this. Yes. Same issue.

EXCEPT...

PREACT 8.2.0 solved it for me.

Thank you. <3

I am not much familiar with JS and just started learning things, but I think I've meet the same issue.
This is my dummy code:

import { h } from 'preact';

export default function ({ webm, mp4, ...props}) {
  return (
    <div className='video-wrapper'>
      <video
        Muted='true'
        AutoPlay='true'
        Loop='true'
        PlaysInline='true'
        Preload='auto'
      >
        <source src={webm} type='video/webm'/>
        <source src={mp4} type='video/mp4'/>
      </video>
    </div>
  );
}

Video is being paused everytime the page is switched from and back with preact-router, even on preact 8.2.1

Hi @surepe - that looks more like you need to use JS native types for booleans:

import { h } from 'preact';

export default function ({ webm, mp4, ...props}) {
  return (
    <div className='video-wrapper'>
      <video
        muted={true}
        autoPlay={true}
        loop={true}
        playsInline={true}
        preload="auto"
      >
        <source src={webm} type='video/webm'/>
        <source src={mp4} type='video/mp4'/>
      </video>
    </div>
  );
}

Hey @developit thanks for suggestion - but sadly it does not matter in this case.
Attributes will just work if specified, even they're passed like

<video autoplay="" loop="" src="https://example.com/test.webm" />

I've did a simple JSFiddle to reproduce this issue. Just switch to another page and get back to home, the video will be paused.
Expected behavoir: video should be started from scratch when we are going back to homepage, not paused.

Sure, this might be not an issue, but it seems like one since I doubt there is must be something special to configure for an basic HTML5 tag.

Thanks!

UPD.
It seems to be working as expected on React.

Just a heads up. Video pausing on DOM move/unmount is straight Google Chrome bug which is been reported and priority has been taken since that affect web's interoperability, and they take that seriously.

Obviously, moving a DOM element like video, audio or canvas shouldn't affect anything in ideal situation.

Actually I was a bit wrong about priority, but anyway: https://bugs.chromium.org/p/chromium/issues/detail?id=737744

hey all,
FYI - having the same issue here. Pausing/Stopping in Safari and Firefox too:
https://codesandbox.io/s/ookzz1v6m6
I also tried the suggestions above with no luck.

@vedam Your issue is actually different from OP's. Preact caches components and their DOM elements, so when the first time video route loads, it works fine; next time it loads, it's the cached element, and "Video pausing on DOM move/unmount is straight Google Chrome bug". I think React doesn't cache components, so every time video loads, it's a new component, and it autoplays fine.

Unfortunately, there is nothing much to do unless we expose one option to disable component caching.

@yaodingyd Thx for this detailed explanation.
Sorry for the noise.

DOM node recycling was removed entirely in Preact 10, so I'm assuming this issue is resolved. Please feel free to re-open if still valid.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jescalan picture jescalan  路  3Comments

paulkatich picture paulkatich  路  3Comments

SabirAmeen picture SabirAmeen  路  3Comments

mizchi picture mizchi  路  3Comments

jasongerbes picture jasongerbes  路  3Comments