Skip to content

Instantly share code, notes, and snippets.

@sz-alpar
Created March 16, 2014 14:34
Show Gist options
  • Save sz-alpar/b8904b0091af063313fd to your computer and use it in GitHub Desktop.
Save sz-alpar/b8904b0091af063313fd to your computer and use it in GitHub Desktop.
Amazon srt player.
// Created by: Szotyori Alpar
// Spent time: 15.03.2014 - 5 hrs
// Spent time: 16.03.2014 - 3 hrs
var DEBUG = true;
// JS loader function from: http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
function loadjscssfile(filename){
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
if (typeof $ === 'undefined') {
if (DEBUG) console.log('loading jQuery');
loadjscssfile('https://code.jquery.com/jquery-1.9.1.min.js');
setTimeout(function () { initPlayer() }, 1000);
} else {
initPlayer();
}
function millisToString(millis) {
var numhours = Math.floor(millis / 3600000),
numminutes = Math.floor((millis % 3600000) / 60000),
numseconds = Math.floor(((millis % 3600000) % 60000) / 1000);
function numToString(num) {
if (num < 10) {
return '0' + num;
} else {
return num;
}
}
return numToString(numhours) + ":" + numToString(numminutes) + ":" + numToString(numseconds);
}
function addVideoResizerAmazon() {
var videoResizer = $('<div></div>')
.attr('id','stl-video-resizer')
.css({
'position': 'absolute',
'bottom': '-5px',
'width': '100%',
'height': '5px',
'background-color': 'gray',
'cursor': 'ns-resize',
'z-index': '99999'
});
var videoPlayerWrapper = $('#player_container_wrapper')
.css('overflow', 'visible')
.append(videoResizer);
var dragStarted = false;
videoResizer.mousedown(function (event) {
dragStarted = true;
});
var prevY = -9999;
$('body').mousemove(function (event) {
if (dragStarted) {
if (prevY == -9999) {
prevY = event.pageY;
}
var deltaY = event.pageY - prevY;
prevY = event.pageY;
var videoPlayerHeight = parseInt(videoPlayerWrapper.css('height').replace('px',''));
videoPlayerHeight += deltaY;
videoPlayerWrapper.css('height', videoPlayerHeight);
}
});
$('body').mouseup(function (event) {
dragStarted = false;
prevY = -9999;
});
}
function createPlayerLoop(totalTime, updateFn, listener) {
var loopInterval,
paused = false,
currentTime,
timeScale = 1,
running = false;
function start() {
if (!loopInterval) {
startInterval();
if (!paused) {
currentTime = 0;
}
paused = false;
running = true;
}
}
function pause() {
if (loopInterval) {
stopInterval();
paused = true;
running = false;
}
}
function stop() {
if (loopInterval) {
stopInterval();
currentTime = 0;
paused = false;
running = false;
}
}
function scale(value) {
if (value) {
timeScale = value;
} else {
return timeScale;
}
}
function seekTo(percent) {
currentTime = totalTime * percent;
if (paused) {
updateFn(currentTime, totalTime);
}
}
function startInterval() {
loopInterval = setInterval(function() {
currentTime += 100 * timeScale;
if (currentTime > totalTime) {
stop();
listener.stopped();
} else {
updateFn(currentTime, totalTime);
}
},100);
}
function stopInterval() {
clearInterval(loopInterval);
loopInterval = undefined;
}
function isRunning() {
return running;
}
return {
'start': start,
'pause': pause,
'stop': stop,
'seekTo': seekTo,
'scale': scale,
'isRunning': isRunning
}
}
function addSubtitlePlayer() {
var srtString,
playerLoop,
subtitlesArray,
sliderControls,
sliderListener;
function parseSrt(srt) {
var lines = srt.split(/\r\n|\r|\n/),
i, j = 0,
subtitles = [],
subtitle = {text:""};
function parseTime(time) {
var startEndTime = time.split(' --> ');
function timeStrToMillis(timeStr) {
var parts, secondParts, hour, minute, second, millisecond;
parts = timeStr.split(':');
hour = parseInt(parts[0]);
minute = parseInt(parts[1]);
secondParts = parts[2].split(',');
second = parseInt(secondParts[0]);
millisecond = parseInt(secondParts[1]);
return millisecond + second * 1000 + minute * 60000 + hour * 3600000;
}
return {
startTime: timeStrToMillis(startEndTime[0]),
endTime: timeStrToMillis(startEndTime[1])
}
}
for (i = 0; i < lines.length; i++) {
if (lines[i].length == 0) {
subtitles.push(subtitle);
subtitle = {text:""};
j = 0;
} else {
if (j == 0) {
subtitle.id = parseInt(lines[i]);
} else if (j == 1) {
subtitle.time = parseTime(lines[i]);
} else {
if (subtitle.text.length > 0) {
subtitle.text = subtitle.text.concat('<br/>' + lines[i]);
} else {
subtitle.text = subtitle.text.concat(lines[i]);
}
}
j++;
if (i == lines.length -1) {
subtitles.push(subtitle);
subtitle = {text:""};
}
}
}
return subtitles;
}
var playerContainer = $('<div></div>')
.attr('id','stl-player-container')
.css({
'position': 'fixed',
'z-index': '10000',
'bottom': '0px',
'width': '100%',
'height': '130px',
'background-color': 'magenta',
'overflow': 'visible',
'line-height': 'normal'
});
$('body').append(playerContainer);
var subtitleEntryField = $('<textarea></textarea>')
.attr('id','stl-input-field')
.css({
'position': 'absolute',
'top': '-53px',
'height': '50px',
'width': '200px'
});
playerContainer.append(subtitleEntryField);
var subtitleEntryFieldSubmit = $('<input/>')
.attr('id','stl-input-field-submit')
.attr('type','button')
.attr('value','Submit')
.css({
'position': 'absolute',
'top': '-28px',
'left': '200px',
'height': '25px',
'width': '80px'
});
var displayedSubtitle;
function subtitleUpdateFn(currentTime, totalTime) {
function findSubtitle() {
var i = 0;
var foundSubtitle;
if (displayedSubtitle) {
if (currentTime > displayedSubtitle.time.endTime) {
i = displayedSubtitle.id;
}
}
for (i; i < subtitlesArray.length; i++) {
if (subtitlesArray[i].time.startTime <= currentTime &&
subtitlesArray[i].time.endTime >= currentTime) {
foundSubtitle = subtitlesArray[i];
break;
}
}
return foundSubtitle;
}
function showSubtitle() {
if (displayedSubtitle) {
subtitleDisplay.html(displayedSubtitle.text);
} else {
subtitleDisplay.html('');
}
}
if (!displayedSubtitle) {
displayedSubtitle = findSubtitle();
showSubtitle()
} else if (displayedSubtitle.time.startTime > currentTime || displayedSubtitle.time.endTime < currentTime) {
displayedSubtitle = findSubtitle();
showSubtitle()
}
sliderControls.updatePosition(currentTime / totalTime);
timeDisplay.text(millisToString(currentTime));
}
sliderListener = {
'positionChanged': function(position) {
playerLoop.seekTo(position);
}
}
loopListener = {
'stopped': function() {
startStopButton.text('>');
sliderControls.updatePosition(0);
}
}
subtitleEntryFieldSubmit.click(function () {
srtString = subtitleEntryField.val();
subtitlesArray = parseSrt(srtString);
var lastItem = subtitlesArray[subtitlesArray.length - 1];
if (lastItem.time) {
playerLoop = createPlayerLoop(subtitlesArray[subtitlesArray.length - 1].time.endTime, subtitleUpdateFn, loopListener);
scaleDisplay.text(playerLoop.scale());
subtitleEntryField.remove();
subtitleEntryFieldSubmit.remove();
}
});
playerContainer.append(subtitleEntryFieldSubmit);
var subtitleDisplay = $('<div></div>')
.attr('id','stl-subtitle-display')
.css({
'width': '100%',
'height': '85%',
'background-color': 'black',
'color': 'white',
'text-align': 'center',
'font-family': 'Arial, Sans-serif',
'font-weight': 'bold',
'font-size': '3em'
});
playerContainer.append(subtitleDisplay);
var controlsContainer = $('<div></div>')
.attr('id','stl-subtitle-controls')
.css({
'width': '100%',
'height': '15%',
'background-color': '#999',
'white-space': 'nowrap'
});
playerContainer.append(controlsContainer);
var startStopButton = $('<div></div>')
.attr('id','stl-start-stop-button')
.css({
'display': 'inline-block',
'width': '20px',
'height': '100%',
'cursor': 'pointer',
'font-weight': 'bold',
'font-size': '1.6em'
})
.text('>');
startStopButton.click(function(event) {
if (!playerLoop) {
return;
}
event.preventDefault();
if (playerLoop.isRunning()) {
playerLoop.pause();
startStopButton.text('>');
} else {
playerLoop.start();
startStopButton.text('||');
}
});
controlsContainer.append(startStopButton);
var slowerButton = $('<div></div>')
.attr('id','stl-slower-button')
.css({
'display': 'inline-block',
'width': '20px',
'height': '100%',
'cursor': 'pointer',
'font-weight': 'bold',
'font-size': '1.6em'
})
.text('-');
slowerButton.click(function(event) {
if (!playerLoop) {
return;
}
event.preventDefault();
playerLoop.scale(playerLoop.scale() - 0.01);
scaleDisplay.text(playerLoop.scale().toFixed(2));
});
controlsContainer.append(slowerButton);
var fasterButton = $('<div></div>')
.attr('id','stl-faster-button')
.css({
'display': 'inline-block',
'width': '20px',
'height': '100%',
'cursor': 'pointer',
'font-weight': 'bold',
'font-size': '1.6em'
})
.text('+');
fasterButton.click(function(event) {
if (!playerLoop) {
return;
}
event.preventDefault();
playerLoop.scale(playerLoop.scale() + 0.01);
scaleDisplay.text(playerLoop.scale().toFixed(2));
});
controlsContainer.append(fasterButton);
var scaleDisplay = $('<div></div>')
.attr('id','stl-scale-display')
.css({
'display': 'inline-block',
'width': '40px',
'height': '100%',
'font-weight': 'bold',
'font-size': '1.1em'
});
controlsContainer.append(scaleDisplay);
var timeDisplay = $('<div></div>')
.attr('id','stl-time-display')
.css({
'display': 'inline-block',
'width': '60px',
'height': '100%',
'font-weight': 'bold',
'font-size': '1.1em'
});
controlsContainer.append(timeDisplay);
function addSlider(container, listener) {
var slider = $('<div></div>')
.attr('id','stl-slider')
.css({
'display': 'inline-block',
'width': '90%',
'height': '100%',
'background-color': 'gray'
});
container.append(slider);
var thumb = $('<div></div>')
.attr('id', 'stl-slider-thumb')
.css({
'display': 'inline-block',
'position': 'relative',
'left': '0px',
'width': '10px',
'height': '100%',
'background-color': '#333',
'cursor': 'pointer'
});
slider.append(thumb);
var dragStarted = false;
thumb.mousedown(function (event) {
dragStarted = true;
});
var prevX = -9999;
$('body').mousemove(function (event) {
event.preventDefault();
if (dragStarted) {
if (prevX == -9999) {
prevX = event.pageX;
}
var deltaX = event.pageX - prevX;
prevX = event.pageX;
var thumbLeft = parseInt(thumb.css('left').replace('px',''));
thumbLeft += deltaX;
if (thumbLeft >= 0 && thumbLeft + thumb.width() <= slider.width()) {
thumb.css('left', thumbLeft + 'px');
listener.positionChanged(getPosition());
}
}
});
$('body').mouseup(function (event) {
dragStarted = false;
prevY = -9999;
});
function updatePosition(percent) {
if (!dragStarted) {
var thumbPosition = Math.max(0, (slider.width() * percent) - thumb.width());
thumb.css('left', thumbPosition + 'px');
}
}
function getPosition() {
var thumbLeft = parseInt(thumb.css('left').replace('px','')),
percent = thumbLeft / (slider.width() - thumb.width());
return percent;
}
return {
'updatePosition': updatePosition,
'getPosition': getPosition
}
}
sliderControls = addSlider(controlsContainer, sliderListener);
}
function cleanUp() {
$('#stl-player-container').remove();
$('#stl-video-resizer').remove();
}
function initPlayer() {
if (DEBUG) console.log('initialize the player');
cleanUp();
addSubtitlePlayer();
addVideoResizerAmazon();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment