0

HTML layer: change <video> element with jquery always blanks the screen for 3secs

Hi there,
I have a problem with some video background divs in a HTML layer.
I need to change the video source in a div. My div is as follows:


<div id="videowrapper0">
<video autoplay muted loop class="myVideo">
<source src="1197-1080.mp4" type="video/mp4">
</video>
</div>


When I try to change the content of the div with jquery, there is always a black screen for about 3 seconds between the two videos with a BS XT1144:

var videocontent = '<video autoplay muted loop id="myVideo"><source src="1547-1080.mp4" type="video/mp4"></video>';
$('#videowrapper0').html(videocontent);

I also tried to put  all four video divs on top of each other an just show/hide the divs, but in this case, there is always a black screen.

On my computer this runs well with both versions.

Any idea how to preload the video and prevent the 3secs black?

Thanks in advance.

10 comments

  • 0
    Avatar
    Bright Scripters info[at]brightscripters.com

    You might find Web Inspector useful. It basically allows use of DevTools, which would give you access to error messages and more.

    https://docs.brightsign.biz/display/DOC/HTML+Best+Practices#HTMLBestPractices-WebInspectorweb_inspector

  • 0
    Avatar
    Keivan

    I use a HTML5 video poster to "hide" this problem... and it works better in never FW versions..

  • 0
    Avatar
    Marcel

    @Keivan: good idea. Never thought about it. Doesn´t solve my problem but makes it better.

    @Bright Scripters: I think, Web Inspector is not the right tool beause I´m getting no errors, just a delay.

    Where can I find some specs, which codec/video settings are the "fastest" for HTML video?
    There are so many codecs/bitrates/variations how to encode a video.

  • 0
    Avatar
    Keivan

    I only show a video that are 470x470px (so the video specs is based on the size converted to a 16:9 aspect)

    What I use and get a subsecond delay/blank is:

    Latest FW 8.0.127 (on older 7.x I had a really long delay)

    Video H264 470x264, Framerate 25

    Most important I don't use any form of HLS/Adaptive delivery because I've seen long delays in starting the videos and also strange things like sound skipping when video changes resolution, occasional premature end of video, video timing not correct (time of video and what time the video element reports), so I guess the HLS/Adaptive part is really buggy

  • 0
    Avatar
    Marcel

    I´m using only local video files.
    But my programming shows a really weird behaviour.
    Here is my code:
    HTML:

    <div id="videowrapper0"></div>

    <div id="videowrapper1"><video autoplay muted loop id="vid0" ><source src="AdobeStock_177023962.mov.mp4" type="video/mp4"></video></div>
     
    JS:
     
    function showVideo(video){

        if (video == 0) {var videocontent = '<video  autoplay muted loop id="vid0" ><source src="AdobeStock_177023962.mov.mp4" type="video/mp4"></video>';}

        if (video == 1) {var videocontent = '<video  autoplay muted loop id="vid1" ><source src="AdobeStock_177023962.mov_1.mp4" type="video/mp4"></video>';}

        if (video == 2) {var videocontent = '<video  autoplay muted loop id="vid2" ><source src="AdobeStock_177023962.mov_2.mp4" type="video/mp4"></video>';}

        if (video == 3) {var videocontent = '<video  autoplay muted loop id="vid3" ><source src="AdobeStock_177023962.mov_3.mp4" type="video/mp4"></video>';}

        

        if ($('#videowrapper0').is(':empty')){

            $("#videowrapper0").css('z-index', 1);

            $("#videowrapper1").css('z-index', 2);

            $('#videowrapper0').html(videocontent);

            setTimeout(

                function() 

                {

                    $("#videowrapper1").fadeOut(500);

            }, 2300);

            setTimeout(

                function() 

                {

                    $("#videowrapper0").css('z-index', 2);

                    $("#videowrapper1").css('z-index', 1);

                    var videocontent2 = '';

                    $('#videowrapper1').html(videocontent2);

                    $("#videowrapper1").fadeIn(1);

            }, 2800);

        }

        if ($('#videowrapper1').is(':empty')){

            $("#videowrapper1").css('z-index', 1);

            $("#videowrapper0").css('z-index', 2);

            $('#videowrapper1').html(videocontent);

            setTimeout(

                function() 

                {

                    $("#videowrapper0").fadeOut(500);

            }, 2300);

            setTimeout(

                function() 

                {

                    $("#videowrapper1").css('z-index', 2);

                    $("#videowrapper0").css('z-index', 1);

                    var videocontent2 = '';

                    $('#videowrapper0').html(videocontent2);

                    $("#videowrapper0").fadeIn(1);

            }, 2800);

        }   

    }
    As you can see, I´m preloading the new videocontent in a layer, which is underneath the actual layer, wait some time and after that, I´m fading the "old" video layer out.
    After that, I´m "cleaning" the old layer.
    This works good, but only for the first time after a page reload. When I want to change the video for a second time, the new video is not starting at the "$('#videowrapper0').html(videocontent);" moment, but in this moment when "" "#videowrapper1").fadeOut(500);" is executed.
    It should start/preload earlier.
    So, I´m getting a short blank screen. 
    There is absolutelly no difference between the first and second call of the function.
    Is this a bug in the firmware or am I doing something wrong.

    I also tried it with hwz-mode: no difference (of course, no fade because of the missing CSS transitions).

  • 0
    Avatar
    Keivan

    Not sure, but the problems I've had been to the problems with HLS/Adaptive formats.

    Another problem I've had is that I need to set the video src no null/nothing and then do a load() to clear up internal video resources (decoders), you only have a limited amount if hardware decoders, depending of model.

    Ex, set src, load(), when finished I src='', load():

    //Src
    player.src = _VideoUrl;

    //PreLoad Video
    player.load();

    //Attach when Video ended
    player.onended = function () {
    //UnLoad
    player.src = '';
    player.load();
    }

    So if you are using a never model of the player you probably have 2HD decoders and then you only can have 2 videos loaded at the same time, so what I do is to set the src to the video video at maximum 2 at the time and then as soon as the first video is finished I set src to null and load() (to tell that is need to free the decoder for use, then load the next video up (in your case video 2), set the src and load() to pre-load the video)

    Another thing I've done is the set the video decoder setup in javascript code (so I can even name to decoder if needed), ex:

    var video_mode = new BSVideoMode();
    video_mode.SetDecoderMode("HD1", "HD", 1, "decoder_video", false);
    video_mode.SetDecoderMode("HD2", "HD", 1, "decoder_overlay", false);

    When I start a video I can set Video attribute to specify decoder:
    .setAttribute("hwz", "z-index:1; fade:never; decoder:decoder_video;");

    Hope it helps

    //

     

  • 0
    Avatar
    Marcel

    @Keivan
    Can you please post the full code?
    I mean, also the HTML part of it.

  • 1
    Avatar
    Keivan

    No not really because all my video elements are created by code

    One difference I do is the reuse the HTML5 video elements so in this case I would either only have 2 elements and alternating then

    But the only part really missing from the example is (I'll try to put this together to pseud working code) (this is TypeScript code & jQuery):

    <div id="videowrapper0"><video muted loop id="vid0" ><source src="" type="video/mp4"></video></div>
    <div id="videowrapper1"><video muted loop id="vid1" ><source src="" type="video/mp4"></video></div>
    function showVideo() {
    //Play First
    playVideo('vid0', 'AdobeStock_177023962.mov.mp4', 2300);

    setTimeout(function () {
    //Play Second
    playVideo('vid1', 'AdobeStock_177023962.mov_1.mp4', 2300);
    }, 2500);

    setTimeout(function () {
    //Play Third
    playVideo('vid0', 'AdobeStock_177023962.mov_2.mp4', 2300);
    }, 2500);

    setTimeout(function () {
    //Play Forth
    playVideo('vid1', 'AdobeStock_177023962.mov_3.mp4', 2300);
    }, 2500);
    }


    function playVideo(videoId: string, videoUrl: string, timeToPlay: number) {
    //Src/Load
    let playerVideo: HTMLVideoElement = <HTMLVideoElement>$(videoId)[0];
    if (playerVideo) {
    //Src
    playerVideo.src = videoUrl;

    //Set HWZ Attributes (Use HWZ)
    playerVideo.setAttribute("hwz", "z-index:-1; fade:never;");

    //Set Poster (if needed)
    playerVideo.poster = videoUrl.replace('.mp4', '.png');

    //PreLoad Video
    playerVideo.load();

    //Attach when Video ended
    playerVideo.onended = function () {
    //UnLoad
    playerVideo.src = ''; //Debug
    playerVideo.load(); //Debug
    }

    setTimeout(function () {
    playerVideo.fadeOut(500);
    }, timeToPlay);
    }
    }

    Not sure if this will work, I haven't tested the code, but the key is to reused the video elements (at least for me) and to properly destry/unload/free the video decoders.

  • 0
    Avatar
    Keivan

    Saw a mistake in the code, the initial timing must be set to something as below...

    function showVideo() {
    //Play First
    playVideo('vid0', 'AdobeStock_177023962.mov.mp4', 2300);

    setTimeout(function () {
    //Play Second
    playVideo('vid1', 'AdobeStock_177023962.mov_1.mp4', 2300);
    }, 2500);

    setTimeout(function () {
    //Play Third
    playVideo('vid0', 'AdobeStock_177023962.mov_2.mp4', 2300);
    }, 5000);

    setTimeout(function () {
    //Play Forth
    playVideo('vid1', 'AdobeStock_177023962.mov_3.mp4', 2300);
    }, 7500);
    }
  • 0
    Avatar
    Marcel

    @Keivan: thanks a lot. Your code was not exactly working but it gave me the solution.
    For someone who is interested, here is my working code:

    HTML:

    <body onload="startup();">

        <div id="videowrapper0"><video muted loop id="videoPlayer0">

                <source id="src0" src="" type="video/mp4"></video></div>

        <div id="videowrapper1"><video muted loop id="videoPlayer1">

                <source id="src1" src="" type="video/mp4"></video></div>
     
    JS:
     
    function startup() {

    // I had to preload every video once

        let src1 = 'AdobeStock_177023962_LOOP.mp4';

        $('#src1').attr('src', src1);

        $("#videoPlayer1").get(0).load();

        $("#videoPlayer1").get(0).play();

        let src0 = 'AdobeStock_321119141_LOOP.mp4';

        $('#src0').attr('src', src0);

        $("#videoPlayer0").get(0).load();

        src0 = 'AdobeStock_313148023_LOOP.mp4';

        $('#src0').attr('src', src0);

        $("#videoPlayer0").get(0).load();

        src0 = 'AdobeStock_261682166_LOOP.mp4';

        $('#src0').attr('src', src0);

        $("#videoPlayer0").get(0).load();

        src0 = '';

        $('#src0').attr('src', src0);

        $("#videoPlayer0").get(0).load();   
    showVideo(0);
    }

     

        
    function showVideo(video) {

        if (!$('#src0').attr('src')) {

            if (video == 0) { var src0 = 'AdobeStock_177023962_LOOP.mp4'; }

            if (video == 1) { var src0 = 'AdobeStock_321119141_LOOP.mp4'; }

            if (video == 2) { var src0 = 'AdobeStock_313148023_LOOP.mp4'; }

            if (video == 3) { var src0 = 'AdobeStock_261682166_LOOP.mp4'; }

            $("#videowrapper0").css('z-index', 1);

            $("#videowrapper1").css('z-index', 2);

            $('#src0').attr('src', src0);

            $("#videoPlayer0").get(0).load();

            $("#videoPlayer0").get(0).play();

            setTimeout(

                function () {

                    $("#videowrapper1").fadeOut(500);

                }, 1000);

            setTimeout(

                function () {

                    $("#videowrapper0").css('z-index', 2);

                    $("#videowrapper1").css('z-index', 1);

                    var src1 = '';

                    $('#src1').attr('src', src1);

                    $("#videoPlayer1").get(0).load();

                    $("#videowrapper1").fadeIn(1);

                }, 1800);

        }

        if (!$('#src1').attr('src')) {

            if (video == 0) { var src1 = 'AdobeStock_177023962_LOOP.mp4'; }

            if (video == 1) { var src1 = 'AdobeStock_321119141_LOOP.mp4'; }

            if (video == 2) { var src1 = 'AdobeStock_313148023_LOOP.mp4'; }

            if (video == 3) { var src1 = 'AdobeStock_261682166_LOOP.mp4'; }

            $("#videowrapper1").css('z-index', 1);

            $("#videowrapper0").css('z-index', 2);

            $('#src1').attr('src', src1);

            $("#videoPlayer1").get(0).load();

            $("#videoPlayer1").get(0).play();

            setTimeout(

                function () {

                    $("#videowrapper0").fadeOut(500);

                }, 1000);

            setTimeout(

                function () {

                    $("#videowrapper1").css('z-index', 2);

                    $("#videowrapper0").css('z-index', 1);

                    var src0 = '';

                    $('#src0').attr('src', src0);

                    $("#videoPlayer0").get(0).load();

                    $("#videowrapper0").fadeIn(1);

                }, 1800);

        }

    }
Please sign in to leave a comment.