Youtube Highlighter using API

Demonstration of using Youtube API to subclip highlights from an uploaded video.

by saiwong

HTML

<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css">
<body>
    
    <div class="well text-center videoContainer">
        <div id="video"></div>
    </div>        
    
    <div class="well text-center">
        <i class="icon-time"></i>
        <span id="currentTime">00:00 / 2:30</span>
        
        <button id="togglePlay" class="offset1 btn btn-primary">Start</button>
        <button id="savePlay" class="btn">Save</button>
    </div>
    
    <div class="well text-center">
        <div class="input-prepend">
            <span class="add-on">Start</span>
            <input class="span2" id="startTime" type="text" />
        </div>
        <div class="input-prepend">
            <span class="add-on">End</span>
            <input class="span2" id="endTime" type="text" />
        </div>
    </div>
    
    <table id="playsTable" class="table table-bordered table-striped empty">
        <thead>
            <tr>
                <td>#</td>
                <td>Description</td>
                <td>Start Time</td>
                <td>End Time</td>
                <td></td>
            </tr>
        </thead>
        <tbody id="playsList">
        </tbody>
    </table>

    <div class="well empty logContainer">
        <div id="log"></div>
        <button id="clearLog" class="btn pull-right"><i class="icon-trash"></i> Clear</button>
    </div>
</body>

CSS

.videoContainer iframe {
    max-width: 480px;
}

#log {
    max-height: 300px;
    overflow-y: auto;
}

.logContainer {
    position: relative;
}

.logContainer #clearLog {
    opacity: 0.3;
    position: absolute;
    right: 19px;
    top: 19px;
}

.logContainer #clearLog:hover {
    opacity: 1;
}

.empty {
    display: none;
}

#playsTable tr {
    cursor: pointer;
}

#playsTable tr:hover td {
    background-color: #ccc;
}

JavaScript

jQuery(function($){
    var player = null,
        playerEl = null,
        logContainer = $('.logContainer'),
        logEl = $('#log'),
        startTimeEl = $('#startTime'),
        endTimeEl = $('#endTime'),
        saveButtonEl = $('#savePlay'),
        playsTable = $('#playsTable'),
        playsEl = playsTable.find('tbody'),
        playCur = 1,
        playerStateMap = {},
        
        // Youtube API Methods
        loadPlayer = function(){
                player = new YT.Player($('#video')[0], {
                width: '100%',
                height: 360,
                videoId: 'ZzMsagY7oRs'
            });
            
            createPlayerStateMap();
            bindPlayerEvents(player);
        },
        
        createPlayerStateMap = function(){
            playerStateMap[YT.PlayerState.ENDED] = "Ended"
            playerStateMap[YT.PlayerState.PLAYING] = "Playing"
            playerStateMap[YT.PlayerState.PAUSED] = "Paused"
            playerStateMap[YT.PlayerState.BUFFERING] = "Buffering"
            playerStateMap[YT.PlayerState.CUED] = "Cued"
        },
        
        bindPlayerEvents = function(player){
            player.addEventListener('onReady', onPlayerReady);
            player.addEventListener('onStateChange', onPlayerStateChange);
        },
        
        onPlayerReady = function(){
            playerEl = $(player.getIframe());
            updatePlayerSize();
        },
        
        onPlayerStateChange = function(resp){
            var state = resp.data;
            if ( state > 0 ) {
                log('player state changed: ' + playerStateMap[state]);
            }
        },
        
        currentTime = function(){
            return player.getCurrentTime();
        },
        
        isPlaying = function(){
            return player && player.getPlayerState() === YT.PlayerState.PLAYING;
        },
        
        play = function(){
            player && player.playVideo();
        },
        
        pause =...