Author: scottbw
Date: Wed Jun 22 13:36:21 2011
New Revision: 1138459
URL: http://svn.apache.org/viewvc?rev=1138459&view=rev
Log:
Committed first version of VTT closed-captioning HTML5 widget
Added:
incubator/wookie/trunk/scratchpad/widgets/vtt/
incubator/wookie/trunk/scratchpad/widgets/vtt/build.xml
incubator/wookie/trunk/scratchpad/widgets/vtt/config.xml
incubator/wookie/trunk/scratchpad/widgets/vtt/icon.png (with props)
incubator/wookie/trunk/scratchpad/widgets/vtt/index.html
incubator/wookie/trunk/scratchpad/widgets/vtt/scripts/
incubator/wookie/trunk/scratchpad/widgets/vtt/scripts/controller.js
Added: incubator/wookie/trunk/scratchpad/widgets/vtt/build.xml
URL:
http://svn.apache.org/viewvc/incubator/wookie/trunk/scratchpad/widgets/vtt/build.xml?rev=1138459&view=auto
==============================================================================
--- incubator/wookie/trunk/scratchpad/widgets/vtt/build.xml (added)
+++ incubator/wookie/trunk/scratchpad/widgets/vtt/build.xml Wed Jun 22 13:36:21
2011
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="build-widget" basedir="." name="widget build file">
+ <property name="wookie.widgets.dir" location="../"/>
+ <property name="widget.shortname" value="vtt"/>
+
+ <import file="../build.xml"/>
+</project>
\ No newline at end of file
Added: incubator/wookie/trunk/scratchpad/widgets/vtt/config.xml
URL:
http://svn.apache.org/viewvc/incubator/wookie/trunk/scratchpad/widgets/vtt/config.xml?rev=1138459&view=auto
==============================================================================
--- incubator/wookie/trunk/scratchpad/widgets/vtt/config.xml (added)
+++ incubator/wookie/trunk/scratchpad/widgets/vtt/config.xml Wed Jun 22
13:36:21 2011
@@ -0,0 +1,46 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<widget xmlns="http://www.w3.org/ns/widgets"
+ id="http://wookie.apache.org/widgets/vtt"
+ version="0.1"
+ width="520"
+ height="480"
+ >
+ <name>VTT</name>
+ <description>A Widget for creating web-VTT caption files</description>
+ <author>Apache Wookie (Incubating) Team</author>
+ <feature name="http://jquerymobile.com" required="true"/>
+
+ <licence>Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.</licence>
+
+</widget>
+
+
+
Added: incubator/wookie/trunk/scratchpad/widgets/vtt/icon.png
URL:
http://svn.apache.org/viewvc/incubator/wookie/trunk/scratchpad/widgets/vtt/icon.png?rev=1138459&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/wookie/trunk/scratchpad/widgets/vtt/icon.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/wookie/trunk/scratchpad/widgets/vtt/index.html
URL:
http://svn.apache.org/viewvc/incubator/wookie/trunk/scratchpad/widgets/vtt/index.html?rev=1138459&view=auto
==============================================================================
--- incubator/wookie/trunk/scratchpad/widgets/vtt/index.html (added)
+++ incubator/wookie/trunk/scratchpad/widgets/vtt/index.html Wed Jun 22
13:36:21 2011
@@ -0,0 +1,141 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="pragma" content="no-cache"/>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <script type="text/javascript" src="scripts/controller.js"
charset="utf-8"></script>
+
+ <!--
+
+ // Removed for now - we may be able to use Playr to do previewing, but
it isn't
+ // necessary for creating the web-vtt file
+ // See http://www.delphiki.com/html5/playr/
+
+ <script type="text/javascript" src="lib/playr.js"
charset="utf-8"></script>
+ <link rel="stylesheet" href="lib/playr.css"/>
+
+ -->
+
+ <!--
+
+ // If you aren't using this in Apache Wookie, uncommment this section
+
+ <script type="text/javascript" src="lib/jquery-1.5.min.js"></script>
+ <script type="text/javascript"
src="lib/jquery.mobile-1.0a4-patched.min.js"></script>
+ <link type="text/css" rel="stylesheet"
href="lib/jquery.mobile-1.0a4.min.css" />
+
+ -->
+
+ <title>VTT</title>
+ </head>
+
+ <body onLoad="Controller.init()">
+ <div data-role="page" id="home">
+
+ <div data-role="header">
+ <h4>VTT Caption Creator</h4>
+ <a href="#add" data-rel="dialog"
data-transition="pop" data-role="button" data-icon="plus">Video</a>
+ <a href="#output" data-rel="dialog" data-transition="pop"
data-role="button" data-icon="grid">VTT</a>
+ </div> <!-- /header -->
+
+ <div data-role="content" class="ui-content">
+ <div id="video_container">
+ <!-- video is placed here -->
+ <div id="no-video">
+ <p>
+ Welcome to the VTT subtitle track creator. Click
the "Video" button to select a video to subtitle.
+ </p>
+ </div>
+ </div>
+
+ <div>
+ <!-- these are the caption creation tools -->
+ <div id="captionTrigger">
+ <button id="startButton"
onclick="Controller.startCaption()">Pause and create caption</button>
+ </div>
+ <div id="captionTools">
+ <div data-role="controlgroup" data-type="horizontal">
+ <input id="captionText"/>
+ <button id="okButton"
onclick="Controller.endCaption()">OK</button>
+ <button id="cancelButton"
onclick="Controller.cancelCaption()">Cancel</button>
+ </div>
+ </div>
+ </div>
+ </div><!-- /content -->
+
+ </div><!-- /page -->
+
+ <!--
+ This is the dialog box that shows the Web-VTT output you've created.
+ --->
+ <div data-role="dialog" id="output">
+ <div data-role="header">
+ <h4>VTT Output</h4>
+ </div> <!-- /header -->
+ <div data-role="content" class="ui-content">
+ <div>
+ <textarea style="width:100%; height:250px; font-family:
courier" id="vtt_out"></textarea>
+ <a href="#preview" data-transition="pop"
data-role="button" onclick="Controller.preview()">Preview</a>
+ <a href="#home" data-transition="pop"
data-direction="reverse" data-role="button">OK</a>
+ </div>
+ </div><!-- /content -->
+ </div><!-- /page -->
+
+
+ <!--
+ This is the dialog box that lets you set the video to show and work on.
+ --->
+ <div data-role="dialog" id="add">
+ <div data-role="header">
+ <h4>Select Video to Use</h4>
+ </div> <!-- /header -->
+ <div data-role="content" class="ui-content">
+ <div data-role="fieldcontain">
+ <label for="input-url-mp4">MP4 URL:</label>
+ <input type="text" name="input-url-mp4"
id="input-url-mp4" value="" />
+ <label for="input-url-ogg">Ogg URL:</label>
+ <input type="text" name="input-url-ogg"
id="input-url-ogg" value="" />
+ </div>
+ <button id="submit-button"
onclick="Controller.setVideo()">OK</button>
+ <a href="#home" data-transition="pop"
data-direction="reverse" data-role="button">Cancel</a>
+ </div><!-- /content -->
+ </div><!-- /page -->
+
+ <!--
+ This is the dialog box that shows a preview of the video with the
subtitle track
+ --->
+ <div data-role="page" id="preview">
+ <div data-role="header">
+ <h4>VTT Preview</h4>
+ </div> <!-- /header -->
+ <div data-role="content" class="ui-content">
+ <div>
+ <p>Unfortunately, Preview doesn't work at the moment -
please fix!</p>
+ <div id="video_preview_container">
+ <!-- video is placed here -->
+ </div>
+ <a href="#home" data-transition="pop"
data-direction="reverse" data-role="button">OK</a>
+ </div>
+ </div><!-- /content -->
+ </div><!-- /page -->
+
+
+
+ </body>
+</html>
\ No newline at end of file
Added: incubator/wookie/trunk/scratchpad/widgets/vtt/scripts/controller.js
URL:
http://svn.apache.org/viewvc/incubator/wookie/trunk/scratchpad/widgets/vtt/scripts/controller.js?rev=1138459&view=auto
==============================================================================
--- incubator/wookie/trunk/scratchpad/widgets/vtt/scripts/controller.js (added)
+++ incubator/wookie/trunk/scratchpad/widgets/vtt/scripts/controller.js Wed Jun
22 13:36:21 2011
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * TODO LIST
+ *
+ * Fix video-with-captions preview
+ * Clear input after user puts in a subtitle
+ * Add keyboard input controls
+ * Cool styling of captions
+ * Dynamic length setting
+ */
+
+/**
+ * The Controller object
+ * This is used to wire up the view and model with actions
+ */
+var Controller = {
+
+ // Setup the controller
+ init:function() {
+ // Set some defaults up in the "video" dialog
+
$("#input-url-mp4").attr("value","http://www.delphiki.com/html5/playr/examples/dw_trailer_low.mp4");
+
$("#input-url-ogg").attr("value","http://www.delphiki.com/html5/playr/examples/dw_trailer_low.ogg");
+
+ // Create new caption set
+ this.captions = [];
+ // Hide the caption editing tools until we have a video
+ $("#captionTrigger").hide();
+ $("#captionTools").hide();
+ },
+
+ select: function(){
+ },
+
+ // Called when the user wants to pause the video
+ // and write a caption. Enables the caption editing controls.
+ startCaption: function(){
+ this.video.pause();
+ this.now = this.video.currentTime;
+ $("#captionTrigger").hide();
+ $("#captionTools").show();
+ },
+
+ // Called when the user has finished writing a caption
+ // Saves the caption and resumes the video
+ endCaption: function(){
+ var caption = {};
+ caption.text = document.getElementById('captionText').value;
+ // We start the captioning 250 milliseconds before the current frame
+ caption.start = this.formatDate(this.now * 1000 - 250);
+ // We end the caption 2 seconds after the caption start
+ caption.end = this.formatDate((this.now + 2) * 1000);
+ this.captions.push(caption);
+ this.updateCaptions();
+ $("#captionTrigger").show();
+ $("#captionTools").hide();
+ this.video.play();
+ },
+
+ // Called if the user cancels writing a caption
+ cancelCaption: function(){
+ $("#captionTrigger").show();
+ $("#captionTools").hide();
+
+ this.video.play();
+ },
+
+ // Update the Web-VTT serialization of the captions
+ updateCaptions: function(){
+ var vtt = "WEBVTT FILE";
+ for(i=0;i<this.captions.length;i++){
+ vtt += "\n";
+ var x = i + 1;
+ vtt += "\n" + x;
+ vtt += "\n" + this.captions[i].start +" --> " +
this.captions[i].end;
+ vtt += "\n" +this.captions[i].text;
+ }
+ document.getElementById('vtt_out').innerHTML = vtt;
+ },
+
+ // Turns a JS date into a Web-VTT timestamp
+ formatDate: function(inputDate){
+ var date = new Date(inputDate);
+ var timestamp;
+ if (date.getHours() < 10){
+ timestamp = "0"+date.getHours();
+ } else {
+ timestamp = date.getHours();
+ }
+ timestamp +=":";
+ if (date.getMinutes() < 10){
+ timestamp += "0"+date.getMinutes();
+ } else {
+ timestamp += date.getMinutes();
+ }
+ timestamp +=":";
+ if (date.getSeconds() < 10){
+ timestamp += "0"+date.getSeconds();
+ } else {
+ timestamp += date.getSeconds();
+ }
+ timestamp += ".";
+ if (date.getMilliseconds() < 100){
+ timestamp += "0";
+ }
+ timestamp += date.getMilliseconds();
+ return timestamp;
+ },
+
+ // Called when OK is clicked in the add video dialog
+ setVideo: function(){
+ // Get the form values
+ var video_src_mp4 = $("#input-url-mp4").attr("value");
+ var video_src_ogg = $("#input-url-ogg").attr("value");
+
+ // Set the video if there is at least one src value
+ if (video_src_mp4 != "" || video_src_ogg != ""){
+ this.resetVideo(video_src_mp4,video_src_ogg, null);
+
+ // Make the caption trigger visible only if there is a valid video
+ $("#captionTrigger").show();
+ }
+
+ // Close the dialog
+ $.mobile.changePage("#home", "pop", true);
+ },
+
+ // Reset the preview dialog
+ preview: function(){
+
+ // Create video tag
+ var video_src_mp4 = $("#input-url-mp4").attr("value");
+ var video_src_ogg = $("#input-url-ogg").attr("value");
+ var track_src = "data:text/plain,"+"\n"+$("#vtt_out").val();
+ var video = this.createVideoTag(video_src_mp4, video_src_ogg,
track_src);
+
+ // Remove any existing preview
+ $('#video_preview_container').empty();
+
+ // Set video tag in the preview container
+ $('#video_preview_container').append(video);
+
+ // Update video tags using Playr
+ this.updateVideoTags();
+ },
+
+ // Reset the video selection
+ resetVideo: function(video_src_mp4, video_src_ogg, track_src){
+
+ // Remove placeholder
+ $("#no-video").remove();
+
+ // Remove old video
+ $("#video_container").empty();
+
+ // Create video tag
+ var video = this.createVideoTag(video_src_mp4, video_src_ogg,
track_src);
+
+ // Set video tag in the container
+ $('#video_container').append(video);
+
+ this.video = document.getElementsByTagName('video')[0];
+
+ // Update video tags using Playr
+ // this.updateVideoTags();
+
+ },
+
+ // Create a video tag
+ createVideoTag: function(video_src_mp4, video_src_ogg, track_src){
+
+ // Create video tag
+ var video = $(document.createElement('video'))
+ .attr('id', 'video')
+ .attr('controls', 'controls')
+ .attr('class','playr_video');
+
+ // Create source tags
+ var mp4source = $(document.createElement('source'))
+ .attr('type','video/mp4')
+ .attr('src', video_src_mp4);
+ video.append(mp4source);
+ var oggsource = $(document.createElement('source'))
+ .attr('type','video/ogg')
+ .attr('src', video_src_ogg);
+ video.append(oggsource);
+
+ // Create subtitle tag
+ if (track_src){
+ var track = $(document.createElement('track'))
+ .attr('kind', 'subtitles')
+ .attr('label', 'WebVTT')
+ .attr('src', track_src)
+ .attr('srclang', 'en')
+ video.append(track);
+ }
+
+ return video;
+ },
+
+ // NOTE I've removed this capability as its not clear what the license
+ // is for Playr.
+ //
+ // Tell Playr to update all video tags in the app
+ updateVideoTags: function(){
+ var video_tags = document.querySelectorAll('video.playr_video');
+ var video_objects = [];
+ for(v = 0; v < video_tags.length; v++){
+ video_objects.push(new Playr(v, video_tags[v]));
+ }
+ }
+}
\ No newline at end of file