Video player in anvil

I’m trying to replicate the behavior referenced in this post

https://anvil.works/forum/t/how-would-i-go-about-showing-a-video-with-anvil/10889

The clone of the app from

https://anvil.works/build#clone:ZJRO34GQF4QDEOBI=BM56FPJ2L46I3BUOUOGKPCFB

works just fine but when i add to my app i get an error when trying to set the source of the video programatically

AttributeError: 'NoneType' object has no attribute 'src'

  • at video, line 22
  • called from Form1, line 20

this is the code

document.getElementById('videoplayer').src=source

so it cannot find the “videoplayer”, i have the custom html template setup as

<video id="videoplayer" width="500" height="250" controls>
  <source src="https://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_1080p_stereo.ogg" type="video/mp4">
  </video>

I’m being stupid but cannot see where the issue lies!

David

document.getElementById is a bit of a footgun when it comes to working with javascript elements in Custom Components.

Firstly this assumes that there is only one of those elements on the page
(what if you have multiple video elements on the screen)

Secondly, your component isn’t on the page until the show event. And the document can only find this element when it is on the page.
(You’re currently trying to find the element in the __init__ method).


Two ways to tackle this.
Although your Component is not yet on the page, the html exists.

def __init__(self, **props):
    self.dom_node = anvil.js.get_dom_node(self)
    self.video_player = self.dom_node.querySelector("video")

But since this has become a common pattern we have a relatviely new API

If you change your html to look like:

<video anvil-name="video_player" width="500" height="250" controls>
    <source src="movie.mp4" type="video/mp4">
</video>

Then your Component has access to the video dom node like so

    @property
    def source(self):
        return self.dom_nodes['video_player'].src

    @source.setter
    def source(self,source):
        self.dom_nodes['video_player'].src = source

6 Likes

my understanding has improved enough now to follow this, thanks!