It's been a long time since I last posted, I really need to make it more of a habit.
All my classes this semester are really piling on the pressure these days, but I guess that's good for me -.-
The last time I blogged about VideoSequencer.js , it was still in its infancy. But since then I have made a whole bunch of changes. The entire structure of it has been reworked (old structure) so that it isn't polluting the global scope anymore.
The first thing I wanted to change was how the videos were handled. Previously, I had set it up so that the sequencer required the id's of video elements on the page to function properly. The videos were simply displayed and hidden as required. go here for the original demo
This proved to be a bad approach, because as I learned, the sequencer may need to handle HUNDREDS of video sources. The obvious solution to my problem was to have it dynamically create and remove video elements as required.
This would make it impossible to know the total length of all the video segments combined, so I decided to use an XML data file to describe the segment URI and its length like in popcorn.js. I rewrote the constructor to grab the XML file name from a "segment-data" attribute in an empty video tag and create an XMLHttpRequest to get the data. It then parses the XML into an array of segment objects, containing src and length attributes.
Once I had the source URIs and the lengths of the segments, It was a matter of modifying the the swap method.
But first I had some performance issues to deal with. The original swap was called when the onended event was thrown. This approach led to noticeable pauses when the videos changed. It was suggested I monitor the current time of the video in comparison to it's duration, and swap milliseconds from the videos completion. This was simple enough to implement.
Handling video creation and removal was no fun at all. There was a lot of failed attempts but a little persistence proved it was possible. It is fairly straight forward. When swap(false) is called by update(), the currently playing video is removed from the page, and a preloaded and hidden video is made visible and altered to become the active video. Then a method named createVideoTag() is called, indicating that the next video in the sequence should be created and hidden while it loads. See what I mean here
The next feature I added creates a way for event listeners to be added to the sequencer. What I mean by this is that instead of adding an event listener to the active video (which is going to be removed at some point) the listener is stored in the videoSequencer object, and is applied to every active video when it is created. (see how it works) I've also added a method that will remove an event from the sequencer if it exists.
The most troublesome feature to get working was the seek method. When I was working with videos that were already preloaded, seeking into them proved not to be a problem. But when I set up tags to be created on the fly, it can lead to issues. For example, say I was watching the first video and wanted to seek to the fifth. Seek would have to create the fifth video and then seek into it. The problem is that you can only seek into a video as far as it has buffered. To minimize the impact of this problem, I decided to pause the video tag after creation and use setInterval to monitor the progress of the video as it loads. Then, when it is sae to seek to the desired time, it does so and end the interval.
Here is the code.
Moving on from that, I decided to try and use code from soda.js, an early framework for a non-standard user interface for media elements. After some tweaking of the code and some small modifications in the calculations of the current time (to reflect my sequence of videos on one time line) It worked! Here's what the code looks like There's obviously a lot to be done in terms of making it look nice and adding more functionality, but actually seeing it represented like that for the first time, felt really good.
SO. now that I assume you've read my rambling, Here's what VideoSequencer looks like today!
Remember, it only works in browsers that support the HTML5 <video> element.
And be patient with the videos.. matrix is not a nice server when it comes to video streaming :(
And before I forget, here's my github repo for VideoSequencer.js