Video playback resume #50946

Closed
opened 2017-03-14 16:56:26 +01:00 by Francesco Siddi · 24 comments

Usability improvement: video playback resume.

This seemed a great staring point, but even getting the example code to run seems not to work https://github.com/Reelhouse/videojs-resume

Usability improvement: video playback resume. This seemed a great staring point, but even getting the example code to run seems not to work https://github.com/Reelhouse/videojs-resume
Francesco Siddi self-assigned this 2017-03-14 16:56:26 +01:00

Changed status to: 'Open'

Changed status to: 'Open'

Added subscriber: @fsiddi

Added subscriber: @fsiddi

Added subscriber: @PeteRobie

Added subscriber: @PeteRobie

The end code I put together as an example seemed to work ok outside of the current code base. Should be able to be modified to fit in an external script.

<script>
        var player = videojs('player');

	$('#player').click(function(){
		localStorage.setItem("playHead", Math.round(parseInt(player.currentTime())));
	});
        $('button').click(function(){
            if(localStorage.getItem("playHead")) {
            	player.currentTime(parseInt(localStorage.getItem("playHead")));
		player.play();
            }
        });
</script>
The end code I put together as an example seemed to work ok outside of the current code base. Should be able to be modified to fit in an external script. ``` <script> var player = videojs('player'); $('#player').click(function(){ localStorage.setItem("playHead", Math.round(parseInt(player.currentTime()))); }); $('button').click(function(){ if(localStorage.getItem("playHead")) { player.currentTime(parseInt(localStorage.getItem("playHead"))); player.play(); } }); </script> ```

Hi Pete. Thanks for providing this code. In the example that you provide on http://peterrobie.com/blenderCloud/ I noticed that the pause button does not pause the video anymore, but it causes it to restart playback from the stored location. Do you have any fix for that?

Hi Pete. Thanks for providing this code. In the example that you provide on http://peterrobie.com/blenderCloud/ I noticed that the pause button does not pause the video anymore, but it causes it to restart playback from the stored location. Do you have any fix for that?

Hi Francesco and thank you for pointing that out. I revised the code and checked to make sure that all buttons function properly. This should function correctly in any HTML5 browser. Let me know if you have any other questions.

<script>
    $('document').ready(function(){
        var player = videojs('player');

        $('#player').click(function(){
            localStorage.setItem("playHead", Math.round(parseInt(player.currentTime())));
        });
        $('button').click(function(){

            var Title = $(this).attr("title");

            switch(Title) {
                case 'Pause':
                    console.log("Switch: Pause");
                    localStorage.setItem("playHead", Math.round(parseInt(player.currentTime())));
                    break;
                
                case 'Play':
                    console.log("Switch: Play");
                    player.play();
                    break;

                case 'Resume':
                    console.log("Switch: Resume");
                    player.currentTime(parseInt(localStorage.getItem("playHead")));
                    player.pause();
                    break;

                default:
            }
        });
    });
</script>
Hi Francesco and thank you for pointing that out. I revised the code and checked to make sure that all buttons function properly. This should function correctly in any HTML5 browser. Let me know if you have any other questions. ``` <script> $('document').ready(function(){ var player = videojs('player'); $('#player').click(function(){ localStorage.setItem("playHead", Math.round(parseInt(player.currentTime()))); }); $('button').click(function(){ var Title = $(this).attr("title"); switch(Title) { case 'Pause': console.log("Switch: Pause"); localStorage.setItem("playHead", Math.round(parseInt(player.currentTime()))); break; case 'Play': console.log("Switch: Play"); player.play(); break; case 'Resume': console.log("Switch: Resume"); player.currentTime(parseInt(localStorage.getItem("playHead"))); player.pause(); break; default: } }); }); </script> ```

Hi Peter,

Thanks for the update. Did you update the demo online as well? I still could not get a reliable payback resume there.
Regarding the code, could you confirm that currently the playhead time is now store only if the video is paused before reloading the page?

Before merging this code we need to take care of some other issue, like associating the playhead with a specific video. Are you available to do it when the time comes?

Thanks!

Hi Peter, Thanks for the update. Did you update the demo online as well? I still could not get a reliable payback resume there. Regarding the code, could you confirm that currently the playhead time is now store only if the video is paused before reloading the page? Before merging this code we need to take care of some other issue, like associating the playhead with a specific video. Are you available to do it when the time comes? Thanks!

Added subscriber: @rootdi

Added subscriber: @rootdi

Any way to work on the mobile with chrome?

<script>
document.addEventListener("DOMContentLoaded", function() {
    
        var player = videojs('player');
    *If local storage is set then show the button* For keeping track of what video we're on.
    var videoSrc = player.currentSrc();
      var videoSrcFile = videoSrc.split("/").pop();

    var PlayheadSet = !!localStorage.getItem(videoSrcFile + "_playHead"); *Set Boolean check for localSotorage key* Allow returning users the ability to resume their video if localStorage is set by showing the button.
    if(PlayheadSet) {
      $("#resumeButton").show();
    } else {
      $("#resumeButton").hide();
    }

    $('#player').click(function(){
      localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime())));
    });

        $('button').click(function(){

      var Title = $(this).attr("title");

      switch(Title) {
        case 'Pause':
          localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime())));
          break;
        
        case 'Play':
          player.play();
          break;

        case 'Resume':
          player.currentTime(parseInt(localStorage.getItem(videoSrcFile + "_playHead")));
                  player.play();
          break;

        default:
      }
        });
  });

  $( window ).on("beforeunload", function(){
    var player = videojs('player');
    // For keeping track of what video we're on.
        var videoSrc = player.currentSrc();
        var videoSrcFile = videoSrc.split("/").pop();
    var PlayheadSet = !!localStorage.getItem(videoSrcFile + "_playHead");
    
    if(PlayheadSet == true) {
      localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime())));
    }
  });


  </script>
Any way to work on the mobile with chrome? ``` <script> document.addEventListener("DOMContentLoaded", function() { var player = videojs('player'); *If local storage is set then show the button* For keeping track of what video we're on. var videoSrc = player.currentSrc(); var videoSrcFile = videoSrc.split("/").pop(); var PlayheadSet = !!localStorage.getItem(videoSrcFile + "_playHead"); *Set Boolean check for localSotorage key* Allow returning users the ability to resume their video if localStorage is set by showing the button. if(PlayheadSet) { $("#resumeButton").show(); } else { $("#resumeButton").hide(); } $('#player').click(function(){ localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime()))); }); $('button').click(function(){ var Title = $(this).attr("title"); switch(Title) { case 'Pause': localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime()))); break; case 'Play': player.play(); break; case 'Resume': player.currentTime(parseInt(localStorage.getItem(videoSrcFile + "_playHead"))); player.play(); break; default: } }); }); $( window ).on("beforeunload", function(){ var player = videojs('player'); // For keeping track of what video we're on. var videoSrc = player.currentSrc(); var videoSrcFile = videoSrc.split("/").pop(); var PlayheadSet = !!localStorage.getItem(videoSrcFile + "_playHead"); if(PlayheadSet == true) { localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime()))); } }); </script> ```

Good morning Robert,

A couple things I'd need to know. Was this happening on Android or on iPhone? What exactly was the issue that you had?

Thanks for pointing this out.

Good morning Robert, A couple things I'd need to know. Was this happening on Android or on iPhone? What exactly was the issue that you had? Thanks for pointing this out.

Hello, thanks for answering. It works perfectly on pc, but I would like it to work on the chrome web browser with android, any ideas? Thank you. Using google translator.

Hello, thanks for answering. It works perfectly on pc, but I would like it to work on the chrome web browser with android, any ideas? Thank you. Using google translator.

I'm having a look at it now to see what I can do.

I'm having a look at it now to see what I can do.

Hey guys,

I found that this is a good solution for the desktop but it does not cover mobile devices since there is no access to the built in media player. I don't know how far we'd like to go on this since using PhoneGap would allow for this feature. Do we want to compile BlenderCloud with PhoneGap to access the mobile media player?

I've also took apart the javascript and rebuilding it so the functionality is down at the moment on my site.

Hey guys, I found that this is a good solution for the desktop but it does not cover mobile devices since there is no access to the built in media player. I don't know how far we'd like to go on this since using PhoneGap would allow for this feature. Do we want to compile BlenderCloud with PhoneGap to access the mobile media player? I've also took apart the javascript and rebuilding it so the functionality is down at the moment on my site.

Hello again, every time I make a change in the php file, the video starts again from the beginning, any solution? Thank you

Hello again, every time I make a change in the php file, the video starts again from the beginning, any solution? Thank you

Hey Robert,

I'm actually back at work and haven't finished reworking the code on my site. Is that where you're trying it out? Basically the code listens for a click event on the pause (either clicking in the video window or pressing pause) and then assigns the name of the video and the timestamp in a key / value pair. Once the person refreshes the page it looks for that key/value and then places a resume button in which it allows the person to resume from the previous time. Nothing is really needed with server side code.

I'm using javascript for the solution and HTML5 local storage.

Hey Robert, I'm actually back at work and haven't finished reworking the code on my site. Is that where you're trying it out? Basically the code listens for a click event on the pause (either clicking in the video window or pressing pause) and then assigns the name of the video and the timestamp in a key / value pair. Once the person refreshes the page it looks for that key/value and then places a resume button in which it allows the person to resume from the previous time. Nothing is really needed with server side code. I'm using javascript for the solution and HTML5 local storage.

My page is dynamic and I do not know why every time I save the video it starts from the beginning. Super weird, I'll keep investigating

If I do not make changes it works correctly.

    <script>
document.addEventListener("DOMContentLoaded", function() {
    
        var player = videojs('player');
    *If local storage is set then show the button* For keeping track of what video we're on.
    var videoSrc = player.currentSrc();
      var videoSrcFile = videoSrc.split("/").pop();

    var PlayheadSet = !!localStorage.getItem(videoSrcFile + "_playHead"); *Set Boolean check for localSotorage key* Allow returning users the ability to resume their video if localStorage is set by showing the button.
    if(PlayheadSet) {
      $("#resumeButton").show();
    } else {
      $("#resumeButton").hide();
    }

    $('#player').click(function(){
      localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime())));
    });

        $('button').click(function(){

      var Title = $(this).attr("title");

      switch(Title) {
        case 'Pause':
          localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime())));
          break;
        
        case 'Play':
          player.play();
          break;

        case 'Resume':
          player.currentTime(parseInt(localStorage.getItem(videoSrcFile + "_playHead")));
                  player.play();
          break;

        default:
      }
        });
  });

  $( window ).on("beforeunload", function(){
    var player = videojs('player');
    // For keeping track of what video we're on.
        var videoSrc = player.currentSrc();
        var videoSrcFile = videoSrc.split("/").pop();
    var PlayheadSet = !!localStorage.getItem(videoSrcFile + "_playHead");
    
    if(PlayheadSet == true) {
      localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime())));
    }
  });


  </script>
My page is dynamic and I do not know why every time I save the video it starts from the beginning. Super weird, I'll keep investigating If I do not make changes it works correctly. ``` <script> document.addEventListener("DOMContentLoaded", function() { var player = videojs('player'); *If local storage is set then show the button* For keeping track of what video we're on. var videoSrc = player.currentSrc(); var videoSrcFile = videoSrc.split("/").pop(); var PlayheadSet = !!localStorage.getItem(videoSrcFile + "_playHead"); *Set Boolean check for localSotorage key* Allow returning users the ability to resume their video if localStorage is set by showing the button. if(PlayheadSet) { $("#resumeButton").show(); } else { $("#resumeButton").hide(); } $('#player').click(function(){ localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime()))); }); $('button').click(function(){ var Title = $(this).attr("title"); switch(Title) { case 'Pause': localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime()))); break; case 'Play': player.play(); break; case 'Resume': player.currentTime(parseInt(localStorage.getItem(videoSrcFile + "_playHead"))); player.play(); break; default: } }); }); $( window ).on("beforeunload", function(){ var player = videojs('player'); // For keeping track of what video we're on. var videoSrc = player.currentSrc(); var videoSrcFile = videoSrc.split("/").pop(); var PlayheadSet = !!localStorage.getItem(videoSrcFile + "_playHead"); if(PlayheadSet == true) { localStorage.setItem(videoSrcFile + "_playHead", Math.round(parseInt(player.currentTime()))); } }); </script> ```

Remove the following outside of the event listener. It's a function and doesn't need to be in there since the main function of this is to listen and not to be executed otherwise.

$('#player').click(function(){

  ...

});

Remove the following outside of the event listener. It's a function and doesn't need to be in there since the main function of this is to listen and not to be executed otherwise. $('#player').click(function(){ ``` ... ``` });

You can enter and play the movie and it works, but if I save the php file it does not work anymore.

http://45.76.235.111/p/1691

You can enter and play the movie and it works, but if I save the php file it does not work anymore. http://45.76.235.111/p/1691

If you pause it's not saving the key/value for local storage. If you're using chrome you can see this by inspecting the page element and going to Application and looking at Storage -> Local Storage and your site name.

Another thing that I noticed is that you're using version 4.12.5 and I'm using 6.4.0.

Let me work on this and I'll post here when I have a stable version of the code.

If you pause it's not saving the key/value for local storage. If you're using chrome you can see this by inspecting the page element and going to Application and looking at Storage -> Local Storage and your site name. Another thing that I noticed is that you're using version 4.12.5 and I'm using 6.4.0. Let me work on this and I'll post here when I have a stable version of the code.

Added subscriber: @dr.sybren

Added subscriber: @dr.sybren
Francesco Siddi was unassigned by Sybren A. Stüvel 2018-08-31 18:22:03 +02:00
Sybren A. Stüvel self-assigned this 2018-08-31 18:22:03 +02:00

I'm working on this in the wip-video-progress branch. We're not storing progress in local storage, but actually in the database, so that it's independent of the machine you're viewing the video on. It's implemented as VideoJS plugin, so it should work in all supported browsers and be independent of the exact element IDs etc.

I'm working on this in the [wip-video-progress](https://developer.blender.org/source/pillar/history/wip-video-progress/) branch. We're not storing progress in local storage, but actually in the database, so that it's independent of the machine you're viewing the video on. It's implemented as VideoJS plugin, so it should work in all supported browsers and be independent of the exact element IDs etc.

Awesome! I add a comment here, to be discussed tomorrow.
Could you outline the reasoning behind storing the watch progress in the user document instead of in the node docs?
I think that storing such info in the node docs would allow for simpler/faster queries both when fetching an individual video and when fetching a series.

Awesome! I add a comment here, to be discussed tomorrow. Could you outline the reasoning behind storing the watch progress in the user document instead of in the node docs? I think that storing such info in the node docs would allow for simpler/faster queries both when fetching an individual video and when fetching a series.

Could you outline the reasoning behind storing the watch progress in the user document instead of in the node docs?

The info we're talking about (who watched which video and where they left off) is private. If we store it in the node document, then each query for that node will have to filter out the private stuff before processing the node further. By default a query for a node will leak private information. Leaking by default didn't seem like a good idea, which is why I chose to store the user-specific information inside the user document. Furthermore, when rendering a video page for a specific user, that user has already been fetched from the database.

> Could you outline the reasoning behind storing the watch progress in the user document instead of in the node docs? The info we're talking about (who watched which video and where they left off) is private. If we store it in the node document, then each query for that node will have to filter out the private stuff before processing the node further. By default a query for a node will leak private information. Leaking by default didn't seem like a good idea, which is why I chose to store the user-specific information inside the user document. Furthermore, when rendering a video page for a specific user, that user has already been fetched from the database.

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'
Sign in to join this conversation.
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: archive/blender-cloud#50946
No description provided.