# View video file in ui

**URL:** <https://discourse.nodered.org/t/view-video-file-in-ui/5240>\
**Category:** Dashboard\
**Created:** [27 November 2018 15:54 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240 "2018-11-27T15:54:15Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dave/32/10827_2.png) [@Dave](https://discourse.nodered.org/u/Dave)\
**Post date:** [27 November 2018 15:54 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240/1 "2018-11-27T15:54:15Z")

</div>

Hi I am trying to display a mp4 video from a file which is in my httpStatic folder, on the dashboard, my code is below, whilst this works I want to add some code in say a function or a template node to inject the file name instead of specifying it in the dashboard template node but I just cannot get my head around it

Thought it would just be a case of sending a msg.payload containing the address into the dashboard template node and replacing the existing address with {{msg,.payload}} but I cannot get it to work ... also I think I may need to refresh the dashboard template node once the new address is injected but nothing I have tried comes close to working, any help would be appreciated

'''{"id":"a63c1856.975b38","type":"ui\_template","z":"4e3c808b.59652","group":"7e6c67d9.c87798","name":"template2","order":27,"width":0,"height":0,"format":"\<div id="video"\>\n \<video width="300" height="200" controls\>\n \<source src= "/video/tl\_27\_11\_2018\_07\_59.mp4"\>\n \n\n \n\n\n\n\n\n\n","storeOutMessages":false,"fwdInMessages":true,"templateScope":"local","x":630,"y":1700,"wires":[["6fae8f9e.2cd19"]]},{"id":"7e6c67d9.c87798","type":"ui\_group","z":"","name":"G\_1","tab":"4e11b05c.70bfc","order":1,"disp":false,"width":"18","collapse":false},{"id":"4e11b05c.70bfc","type":"ui\_tab","z":"","name":"Drivecamlrgscreen","icon":"dashboard","order":5}]'''

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [27 November 2018 20:27 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240/2 "2018-11-27T20:27:44Z")

</div>

Hi Dave,

When the above HTML is inside a template node, I '_think_' you should add something like this in the same template node:

```auto
<script> 
    (function(scope) {
        // Watch for messages being send to this template node
        scope.$watch('msg', function (msg) {      
            if (msg) {
                  var document.getElementById().src = msg.payload;
            }       
         }); 
    })(scope); 
</script>

```

P.S. I haven't tested this code ...

Bart

---

<div class="post-metadata">

**Author:** ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)\
**Post date:** [27 November 2018 22:27 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240/3 "2018-11-27T22:27:46Z")

</div>

If you define your video html elements in a `ui_template` node, replace the `src="/video/xxxx"` with the [angular `ng-src` directive](https://docs.angularjs.org/api/ng/directive/ngSrc) instead:

```
<div id="video">
    <video width="300" height="200" controls>
    <source ng-src="{{msg.payload}}">
</div>

```

Then whenever you pass a new `msg.payload` containing a video url, it should switch to that video source.

---

<div class="post-metadata">

**Author:** ![Dave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dave/32/10827_2.png) [@Dave](https://discourse.nodered.org/u/Dave)\
**Post date:** [28 November 2018 15:17 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240/4 "2018-11-28T15:17:03Z")

</div>

Thanks Steve, slightly modding your code I got it working, however to make it work currently I have to switch to a different tab and back again the results of that loads the new url into the video screen.

```auto
[{"id":"10cda3f5.3f63cc","type":"inject","z":"37539945.991916","name":"test","topic":"","payload":"/video/tl_27_11_2018_13_40.mp4","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1180,"y":1300,"wires":[["a93393a2.28198"]]},{"id":"a93393a2.28198","type":"ui_template","z":"37539945.991916","group":"a4019b6f.6ea158","name":"Vid_screen","order":28,"width":"6","height":"4","format":"<div id=\"video\">\n <video width=\"300\" height=\"200\" controls>\n <source ng-src={{msg.payload}}>\n </video> \n</div>\n\n\n\n\n","storeOutMessages":false,"fwdInMessages":true,"templateScope":"local","x":1380,"y":1300,"wires":[["802a1edd.a3e54"]]},{"id":"8a54008c.02bf4","type":"ui_ui_control","z":"37539945.991916","name":"","x":1730,"y":1300,"wires":[[]]},{"id":"802a1edd.a3e54","type":"trigger","z":"37539945.991916","op1":"3","op2":"4","op1type":"str","op2type":"str","duration":"10","extend":false,"units":"ms","reset":"","bytopic":"all","name":"","x":1560,"y":1300,"wires":[["8a54008c.02bf4"]]},{"id":"a4019b6f.6ea158","type":"ui_group","z":"","name":"G_2","tab":"4e11b05c.70bfc","order":4,"disp":false,"width":"6","collapse":false},{"id":"4e11b05c.70bfc","type":"ui_tab","z":"","name":"Drivecamlrgscreen","icon":"dashboard","order":5}]

```

I guess something like Bart's code that detects when a new msg arrives could just update this specific template node which I would really like to do, but I just cannot get it to work.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [1 December 2018 00:20 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240/5 "2018-12-01T00:20:17Z")

</div>

Hi Dave,

Finally some (few) '_me-time_' at my pc.  
When I use this (updated) code snippet in a template node:

```auto
<div>
     <video id="video" width="100%" heigth="100%"></video>
</div>

<script> 
    (function(scope) {
        // Watch for messages being send to this template node
        scope.$watch('msg', function (msg) {      
            if (msg) {

                var video = document.getElementById('video');
                video.src = msg.payload;
                video.play();
            }       
         }); 
    })(scope); 
</script>

```

Then I can switch (in Chrome) dynamically between movies, by **injecting URLs** referring to different mp4 files:

 ![dynamic_video_src](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/e/ef9dddb46d913ba20d93ff04e356e764611c9051.gif)

Here is the example flow:

```auto
[{"id":"34ebe5b1.ffe0ca","type":"inject","z":"18e47039.88483","name":"Show first stream","topic":"","payload":"https://storage.googleapis.com/coverr-main/mp4/The-Slow-Dock.mp4","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":620,"y":1140,"wires":[["d4643763.1e4478"]]},{"id":"d4643763.1e4478","type":"ui_template","z":"18e47039.88483","group":"b389df50.19473","name":"Vid_screen","order":28,"width":"6","height":"4","format":"<div>\n <video id=\"video\" width=\"100%\" heigth=\"100%\"></video>\n</div>\n\n<script> \n (function(scope) {\n // Watch for messages being send to this template node\n scope.$watch('msg', function (msg) { \n if (msg) {\n\n var video = document.getElementById('video');\n video.src = msg.payload;\n video.play();\n } \n }); \n })(scope); \n</script>\n\n\n\n","storeOutMessages":false,"fwdInMessages":true,"templateScope":"local","x":830,"y":1140,"wires":[[]]},{"id":"1cd37387.83b0bc","type":"inject","z":"18e47039.88483","name":"Show first stream","topic":"","payload":"https://storage.googleapis.com/coverr-main/mp4/Night-Traffic.mp4","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":620,"y":1180,"wires":[["d4643763.1e4478"]]},{"id":"b389df50.19473","type":"ui_group","z":"","name":"G_2","tab":"12ba52b2.c0ce3d","order":4,"disp":false,"width":"6","collapse":false},{"id":"12ba52b2.c0ce3d","type":"ui_tab","z":"","name":"Drivecamlrgscreen","icon":"dashboard","order":5}]

```

Note that recently Google has changed its autoplay [policy](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes). So you cannot use the `autoplay` attribute anymore, and you will get an exception when you do `video.play()` in Javascript. Reason is that they want to avoid that websites start automatically playing unwanted video/audio, which is annoying for users and wastes bandwith. However for your use case, I had to change the policy allow manually back to the old status (which means the user doesn't have to press something before playing):  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/0/0ce762fdea61c351c513169de8cf4d5caf6f1077.png)

Is there anybody around who knows how we can solve this automatically??

Bart

---

<div class="post-metadata">

**Author:** ![hugobox](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hugobox/32/2948_2.png) [@hugobox](https://discourse.nodered.org/u/hugobox)\
**Post date:** [1 December 2018 03:27 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240/6 "2018-12-01T03:27:54Z")

</div>

I had to modify it a bit as my browser was complaining for something else

> **[DOMException: The play() request was interrupted  |  Web
       |  Google...](https://developers.google.com/web/updates/2017/06/play-request-was-interrupted)**
>
> What is really happening with "DOMException: The play() request was interrupted"?

Maybe it'll solve your autoplay as well

```auto
<div>
     <video id="video" width="100%" heigth="100%"></video>
</div>

<script> 
    (function(scope) {
        // Watch for messages being send to this template node
        scope.$watch('msg', function (msg) {      
            if (msg) {

                var video = document.getElementById('video');
                video.src = msg.payload;
                var playPromise = video.play();

                if (playPromise !== undefined) {
                    playPromise.then(_ => {
                      // Automatic playback started!
                      // Show playing UI.
                    })
                    .catch(error => {
                      // Auto-play was prevented
                      // Show paused UI.
                    });
                }
            }       
         }); 
    })(scope); 
</script>
```

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [1 December 2018 14:10 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240/7 "2018-12-01T14:10:44Z")

</div>

Hi @hugobox,

Thanks for the tip!!!  
I tried something similar yesterday, but then I also arrived in the catch part...

To be sure, I have reset again my autoplay policy to the default:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/8/86896985bbd53e026b05bd8369265a700dc02957.png)

Then both your and mine version still work fine. Very weird!

Afterwards I have asked Chrome to make sure that a user gesture is required, before start playing:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/9/9465cfeefd2bb3fc1b08362311f71af5971a6e87.png)

Then both versions still work fine. I don't get it anymore 🥴

Other nodes are also being fixed for the policy changes (see [discussion](https://discourse.nodered.org/t/audio-context-changes/250) and corresponding [pull request](https://github.com/lorentzlasson/node-red-contrib-play-audio/pull/9)), but I don't get how they can get around the user gestures that way ...

P.S. But your version is anyway better than mine ...  
Bart

---

<div class="post-metadata">

**Author:** ![Dave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dave/32/10827_2.png) [@Dave](https://discourse.nodered.org/u/Dave)\
**Post date:** [2 December 2018 17:54 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240/8 "2018-12-02T17:54:47Z")

</div>

Thanks guys, I didn't get a lot of time over the last few days ('me-time' haha) to test and I now have to go out again, but the code is working great on my pc using Chrome, at the moment it doesn't appear to work on my ipad or iphone in safari I will down load & check google browser app later, cheers.

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [21 July 2022 14:06 UTC](https://discourse.nodered.org/t/view-video-file-in-ui/5240/10 "2022-07-21T14:06:22Z")

</div>


