Flowplayer: Configuring a Cumulative Sequence of Video Clips with Playlist & Ipad Plugins
There are several Flowplayer plugins and add-ons available to help webmasters embed video clips on their website. As such, there are several permutations and combinations of configurations that exist. Recently, I had to configure a playlist of several video clips that would automatically play back-to-back using the Flowplayer javascript plugin. Since the help forums and documentation on Flowplayer's site was a bit garbled, I thought it'd help to document my implementation of a playlist with the ipad plugin for future reference.
- be encoded in both MP4 and FLV formats
- be kept to a minimum duration, and compressed as much as possible
- have a few seconds of dead air/fade to black at the end
- the flowplayer playlist plugin (available at http://flowplayer.org/plugins/javascript/playlist.html)
- the flowplayer ipad plugin (available at http://flowplayer.org/plugins/javascript/ipad.html)
In the code blocks below, site-specific implementation variables are denoted in BOLD RED CAPS. Coding comments are in italicized blue.
<script type="text/javascript" src="ABSOLUTE_OR_RELATIVE_PATH_TO/jquery.min.js"></script> <script type="text/javascript" src="RELATIVE_PATH_TO/flowplayer-3.2.6.min.js"></script> <script type="text/javascript" src="RELATIVE_PATH_TO/flowplayer.ipad-3.2.2.min.js"></script> <script type="text/javascript" src="RELATIVE_PATH_TO/flowplayer.playlist-3.0.8.min.js"></script>
<div class="PLAYLIST_CONTAINER_DIV_ID" style="display:none;visibility:hidden;"> <!--CSS INLINE STYLING USED HERE WAS OPTIONAL, you could--> <!--optionally use this division to create an index of video clips to select from.--> <a href="RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_1_FILENAME.mp4"></a> <a href="RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_2_FILENAME.mp4"></a> <a href="RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_N_FILENAME.mp4"></a> <a href="RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_LAST_FILENAME.mp4"></a> </div> <div class="PLAYER_CONTAINER_CSS_WRAPPER"> <a style="background-image:url('RELATIVE_PATH_TO_/GRAPHIC.JPG');" id="PLAYER_CONTAINER_ID"></a> <!--Image above is the player preload poster image--> </div>
/* * function flowplayer(player_container_id, {flash_wrapper, embed settings}, commercial key, clip {}, * playlist[], plugins{} ).ipad().playlist(playlist_container_id,variables) * function initializes an instance of flowplayer */ flowplayer(PLAYER_CONTAINER_ID, {src: "flowplayer_js/flowplayer.commercial-3.2.7.swf"}, { key: 'COMMERCIAL_LICENSE_KEY_AS_STRING', clip : { autoBuffering: true, duration: CUMULATIVE_TIME_OF_CLIPS_WHEN_PLAYED_BACK_TO_BACK //note last item in clip array does not have a trailing comma }, playlist: [ //each segment or video clip is an element in the playlist array { url: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_1_FILENAME.flv", ipadUrl: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_1_FILENAME.mp4", duration: vid_duration = DURATION_OF_1st_VIDEO_SEGMENT_AS_INTEGER, position: prevEnd = calcTimeIndex(vid_duration,0), autoPlay: false // disable automatic playing on page load/launch of player }, //end 1st clip { url: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_2_FILENAME.flv", ipadUrl: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_2_FILENAME.mp4", duration: vid_duration = DURATION_OF_2nd_VIDEO_SEGMENT_AS_INTEGER, position: prevEnd = calcTimeIndex(vid_duration,prevEnd), autoPlay: true // enable automatic play of this video segment upon load }, //end 2nd clip { url: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_N_FILENAME.flv", ipadUrl: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_N_FILENAME.mp4", duration: vid_duration = DURATION_OF_2nd_VIDEO_SEGMENT_AS_INTEGER, position: prevEnd = calcTimeIndex(vid_duration,prevEnd), autoPlay: true // enable automatic play of this video segment upon load }, //end nth clip { url: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_LAST_FILENAME.flv", ipadUrl: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_LAST_FILENAME.mp4", duration: vid_duration = DURATION_OF_LAST_VIDEO_SEGMENT_AS_INTEGER, position: prevEnd = calcTimeIndex(vid_duration,prevEnd), autoPlay: true // enable automatic play of this video segment upon load } // end clip NOTE- last item in playlist array does not have a trailing comma ], //end playlist plugins: { controls: { playlist: true, //enable the controls plugin to show playlist buttons stop: true } } }).ipad().playlist(PLAYLIST_CONTAINER_DIV_ID_AS_STRING, {loop:true} ); // be sure to set the playlist loop variable to true to automatically load the next clip/segment // upon completion of the current segment; otherwise, users will need to push the // Fast Forward Button to skip to the next clip/segment. /* * function calcTimeIndex(duration,prevEnd) * function: calculates cumulative time index for end of current segment/start of next segment * function arguments: duration of new clip, cumulative time index up to this clip * function returns: cumulative time index at end of newly added clip */ function calcTimeIndex(duration,prevEnd) { var starttime, endtime; starttime = prevEnd; endtime = starttime + duration + 1; return endtime; }
In the implementation above, the playlist clips were defined within the javascript call itself, but cumulative time indices were calculated using the calcTimeIndex() function instead of manually tallying the start and stop times for each segment.
An example of the above code in action can be found at SaintClares.org/saintclares247, launched December 23, 2011. Be sure to watch for my next post about implementing google analytics to track individual flowplayer events within a playlist!