# HTMLtemplate webm intro =\> loop =\> outro

**URL:** <https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465>\
**Category:** General\
**Created:** [November 19, 2019, 12:38pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465 "2019-11-19T12:38:30Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Maurice78](https://casparcgforum.org/letter_avatar_proxy/v4/letter/m/edb3f5/32.png) [@Maurice78](https://casparcgforum.org/u/Maurice78)\
**Post date:** [November 19, 2019, 12:38pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/1 "2019-11-19T12:38:31Z")

</div>

Hi all

I’m new to using vidoe in a HTML template.  
i have it working with alpha which is nice.  
with this ffmpeg command i make the clips

> ffmpeg.exe -i .\test3.mov -f webm -c:v libvpx -b:v 10M -acodec libvorbis -auto-alt-ref 0 test3.webm

but i was wondering if anyone has a example off the following, or some hints 😉

@play()  
start a intro clip =\> seamless going into a looping clip looping forever /waiting for stop

and then  
@stop()  
or go directly to the outro clip (produced so it can start anywhere in the loop)  
or wait for the loop clip to reach it’s end an then start the outro clip

thanks

---

<div class="post-metadata">

**Author:** ![rrebuffo](https://casparcgforum.org/user_avatar/casparcgforum.org/rrebuffo/32/165_2.png) [@rrebuffo](https://casparcgforum.org/u/rrebuffo)\
**Post date:** [November 19, 2019, 1:07pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/2 "2019-11-19T13:07:03Z")

</div>

Make one clip stitched toghether, then:

```
    let _loop = document.getElementById('loop');

    function checkLoop()
    {
        if (_loop.currentTime > 33)
        {
            _loop.currentTime = 5;
            _loop.play();
        }
    }
    _loop.addEventListener("timeupdate", checkLoop, false);

```

and in stop()

```
        _loop.currentTime = 35.7;
        _loop.play();
```

---

<div class="post-metadata">

**Author:** ![hreinnbeck](https://casparcgforum.org/user_avatar/casparcgforum.org/hreinnbeck/32/154_2.png) [@hreinnbeck](https://casparcgforum.org/u/hreinnbeck)\
**Post date:** [November 19, 2019, 1:13pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/3 "2019-11-19T13:13:29Z")

</div>

You’ll want to have every frame as a keyframe:  
`-g 1 -keyint_min 1 -force_key_frames 1`

You can then seek to a frame with something like:

```auto
function seekFrame(fr) {
	bgvid.currentTime = (fr*40)/1000; // 25fps/1000 = 40
}

```

I actually play videos using rAF as a timer (i.e. the video is always paused and I just seek to frames in it).

---

<div class="post-metadata">

**Author:** ![rrebuffo](https://casparcgforum.org/user_avatar/casparcgforum.org/rrebuffo/32/165_2.png) [@rrebuffo](https://casparcgforum.org/u/rrebuffo)\
**Post date:** [November 19, 2019, 1:24pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/4 "2019-11-19T13:24:05Z")

</div>

> [@hreinnbeck](#):
>
> (fr\*40)/1000

@hreinnbeck Do you recommend using 25fps video? Is that better for performance?  
I usually use 50p videos or sequences for all the graphics.

---

<div class="post-metadata">

**Author:** ![hreinnbeck](https://casparcgforum.org/user_avatar/casparcgforum.org/hreinnbeck/32/154_2.png) [@hreinnbeck](https://casparcgforum.org/u/hreinnbeck)\
**Post date:** [November 19, 2019, 1:25pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/5 "2019-11-19T13:25:26Z")

</div>

That’s just ripped out of a project that was delivered with 25p video assets, I usually do everything at 50. Another thing to note with my rAF solution of playing is that 1) it will be frame accurate for Caspar output (since it takes over rAF) and 2) it’s the only way of reliably getting time for video in browsers (timeupdate is not guaranteeed to fire rapidly enough).

---

<div class="post-metadata">

**Author:** ![rrebuffo](https://casparcgforum.org/user_avatar/casparcgforum.org/rrebuffo/32/165_2.png) [@rrebuffo](https://casparcgforum.org/u/rrebuffo)\
**Post date:** [November 19, 2019, 1:30pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/6 "2019-11-19T13:30:42Z")

</div>

> [@hreinnbeck](#):
>
> project that was delivered with 25p

Oh! so that’s not just a thing over here.

> [@hreinnbeck](#):
>
> timeupdate is not guaranteeed to fire rapidly enough

Good to know! That answers some other questions

---

<div class="post-metadata">

**Author:** ![noumaan](https://casparcgforum.org/letter_avatar_proxy/v4/letter/n/dfb087/32.png) [@noumaan](https://casparcgforum.org/u/noumaan)\
**Post date:** [November 19, 2019, 2:31pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/7 "2019-11-19T14:31:35Z")

</div>

> [@rrebuffo](#):
>
> and in stop()
> 
> ```auto
> _loop.currentTime = 35.7;
> _loop.play();
> 
> ```

with seek command can we add transition like mix ?

---

<div class="post-metadata">

**Author:** ![Maurice78](https://casparcgforum.org/letter_avatar_proxy/v4/letter/m/edb3f5/32.png) [@Maurice78](https://casparcgforum.org/u/Maurice78)\
**Post date:** [November 19, 2019, 3:15pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/8 "2019-11-19T15:15:13Z")

</div>

Thanks for the info all

will play with this later

again thanks soo far

---

<div class="post-metadata">

**Author:** ![rrebuffo](https://casparcgforum.org/user_avatar/casparcgforum.org/rrebuffo/32/165_2.png) [@rrebuffo](https://casparcgforum.org/u/rrebuffo)\
**Post date:** [November 19, 2019, 4:33pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/9 "2019-11-19T16:33:17Z")

</div>

> [@noumaan](#):
>
> with seek command can we add transition like mix ?

I used two video tags for that effect so the loop keeps playing while fading out and the outro fades in a couple of frames earlier.

---

<div class="post-metadata">

**Author:** ![Maurice78](https://casparcgforum.org/letter_avatar_proxy/v4/letter/m/edb3f5/32.png) [@Maurice78](https://casparcgforum.org/u/Maurice78)\
**Post date:** [November 20, 2019, 1:45pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/10 "2019-11-20T13:45:59Z")

</div>

Again thank you all love the community

I came up with this anyone seeing trouble in this

```auto
    <script>
    let loop = false
    let playHead = {
    	pos: 0,
    	loopPos: 0,
    	loop: {
    		in: 100,
    		out: 400
    	},
    	end: 500
    	}
    

    function play () {
    	TweenMax.to(playHead, 1, {pos:playHead.loop.in, ease:Linear.easeNone, onUpdate: updatePlayHead, onComplete:loopstart})
		let myPlayer1 = document.getElementById('myPlayer1')
    	TweenMax.to(myPlayer1, 1, {opacity: 1})
   		let myPlayer2 = document.getElementById('myPlayer2')
    	TweenMax.to(myPlayer2, 1, {opacity: 1})
    }

    function stop () {
    	loop = false
    	TweenMax.to(playHead, 1, {pos:playHead.end, onUpdate: updatePlayHead})
    	TweenMax.to(myPlayer1, 1, {opacity: 0})
    	TweenMax.to(myPlayer2, 1, {opacity: 0})
    }

    function loopstart () {
    	loop = true
    	playHead.pos = playHead.loop.in
    	seek(playHead.pos)
    }

    function update () {
        
    }

    function updatePlayHead () {
    	seek(playHead.pos) 
    }

    function seek (frame) {
    	let myPlayer1 = document.getElementById('myPlayer1')
    	let myPlayer2 = document.getElementById('myPlayer2')
    	myPlayer1.currentTime = (frame * 20)/1000;
    	myPlayer2.currentTime = (frame * 20)/1000;
    }
    
    function hearthBeat() {
    	window.requestAnimationFrame(hearthBeat)
    	if (loop) {
    		playHead.pos++
    		seek(playHead.pos)
    		if (playHead.pos === playHead.loop.out) {
    			playHead.pos = playHead.loop.in
    		}
    	}
    }

    window.requestAnimationFrame(hearthBeat)
    </script>
    <style>
    	#myPlayer1{
    		opacity: 0
    	}
    	#myPlayer2{
    		opacity: 0
    	}
    </style>

```

---

<div class="post-metadata">

**Author:** ![hreinnbeck](https://casparcgforum.org/user_avatar/casparcgforum.org/hreinnbeck/32/154_2.png) [@hreinnbeck](https://casparcgforum.org/u/hreinnbeck)\
**Post date:** [November 20, 2019, 4:28pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/11 "2019-11-20T16:28:04Z")

</div>

> [@Maurice78](#):
>
> function hearthBeat() { window.requestAnimationFrame(hearthBeat) …

You’ll want rAF at the end.

Do `let myPlayer1 = document.getElementById('myPlayer1')` etc… outside of the functions and only once.

Don’t count the frames, check currentTime

---

<div class="post-metadata">

**Author:** ![Maurice78](https://casparcgforum.org/letter_avatar_proxy/v4/letter/m/edb3f5/32.png) [@Maurice78](https://casparcgforum.org/u/Maurice78)\
**Post date:** [November 20, 2019, 5:43pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/12 "2019-11-20T17:43:02Z")

</div>

Thanks @hreinnbeck

> You’ll want rAF at the end.

Yep i understand why

> Do let myPlayer1 = document.getElementById(‘myPlayer1’) etc… outside of the functions and only once.

true i understand

> Don’t count the frames, check currentTime

i guess you mean this part

> if (playHead.pos === playHead.loop.out) {  
> playHead.pos = playHead.loop.in  
> }

it seems too work nicely.  
Where do you see the problem?  
What could go wrong?

---

<div class="post-metadata">

**Author:** ![hreinnbeck](https://casparcgforum.org/user_avatar/casparcgforum.org/hreinnbeck/32/154_2.png) [@hreinnbeck](https://casparcgforum.org/u/hreinnbeck)\
**Post date:** [November 20, 2019, 6:56pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/13 "2019-11-20T18:56:23Z")

</div>

You can’t be sure that the video has actually presented (displayed/rendered) the frame. The closest thing to being sure of that is to check currenttime. I’d also have that as \>= just to be sure you don’t miss a frame and then it just plays till the end.

---

<div class="post-metadata">

**Author:** ![ouellettec](https://casparcgforum.org/user_avatar/casparcgforum.org/ouellettec/32/596_2.png) [@ouellettec](https://casparcgforum.org/u/ouellettec)\
**Post date:** [November 21, 2019, 6:26am UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/14 "2019-11-21T06:26:41Z")

</div>

May I also recommend using a [can play](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canplay_event) event listener if you are using a HTML `<video>` element. This combined with a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) and an [on error function](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/error) can make for an asynchronous video load and error handling fallback.

---

<div class="post-metadata">

**Author:** ![rrebuffo](https://casparcgforum.org/user_avatar/casparcgforum.org/rrebuffo/32/165_2.png) [@rrebuffo](https://casparcgforum.org/u/rrebuffo)\
**Post date:** [November 23, 2019, 12:23am UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/15 "2019-11-23T00:23:15Z")

</div>

> [@hreinnbeck](#):
>
> Don’t count the frames, check currentTime

How do you seek to the next correct time-accurate frame without counting frames? I’m lost.  
I understand rAF throttles down the execution so every frame would take more than 20ms to update in some cases.

---

<div class="post-metadata">

**Author:** ![hreinnbeck](https://casparcgforum.org/user_avatar/casparcgforum.org/hreinnbeck/32/154_2.png) [@hreinnbeck](https://casparcgforum.org/u/hreinnbeck)\
**Post date:** [November 23, 2019, 2:19pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/16 "2019-11-23T14:19:12Z")

</div>

Just check this: [https://casparcg.net/webm/](https://casparcg.net/webm/)

---

<div class="post-metadata">

**Author:** ![Maurice78](https://casparcgforum.org/letter_avatar_proxy/v4/letter/m/edb3f5/32.png) [@Maurice78](https://casparcgforum.org/u/Maurice78)\
**Post date:** [November 23, 2019, 3:01pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/17 "2019-11-23T15:01:15Z")

</div>

Nice example thanks !

i totally get what you are doing.

in my case i am using 2 clips driven by the same var now (2 club logo’s that can be chosen)

i guess your solutions plays all the frame’s nicely but can get out off sync when a frame from one player is late.

where my idea skips a frame (in a dirty way) when a frame is late leaving the 2 clips in sync

very nice solution though !!

---

<div class="post-metadata">

**Author:** ![ouellettec](https://casparcgforum.org/user_avatar/casparcgforum.org/ouellettec/32/596_2.png) [@ouellettec](https://casparcgforum.org/u/ouellettec)\
**Post date:** [November 23, 2019, 3:42pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/18 "2019-11-23T15:42:27Z")

</div>

I am curious why this video is being loaded as one element. Why wouldn’t the intro, loop and outro be three separate elements that can be loaded and adjusted independently from each other? Then you wouldn’t need to do the frame checks but instead set the loop video to `loop=true` and call it a day. Just a thought 🙂

---

<div class="post-metadata">

**Author:** ![hreinnbeck](https://casparcgforum.org/user_avatar/casparcgforum.org/hreinnbeck/32/154_2.png) [@hreinnbeck](https://casparcgforum.org/u/hreinnbeck)\
**Post date:** [November 23, 2019, 3:46pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/19 "2019-11-23T15:46:21Z")

</div>

It’s a lot more performant and it easily allows to finish loops before going into outro (which I consider a hallmark of professional graphics).

---

<div class="post-metadata">

**Author:** ![rrebuffo](https://casparcgforum.org/user_avatar/casparcgforum.org/rrebuffo/32/165_2.png) [@rrebuffo](https://casparcgforum.org/u/rrebuffo)\
**Post date:** [November 23, 2019, 3:50pm UTC](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465/20 "2019-11-23T15:50:25Z")

</div>

At least in my line of thoughts, the goal is to load all the elements at the same time and not to worry if something gets left behind, but I’m actually not sure the seeked video frames get loaded faster than a new video.

[Next page](https://casparcgforum.org/t/htmltemplate-webm-intro-loop-outro/2465.md?page=2)
