Created
March 16, 2016 13:05
-
-
Save karlbright/dcddaa42cf8f3337a596 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs') | |
var path = require('path') | |
var subtitlesParser = require('subtitles-parser') | |
var childProcess = require('child_process') | |
var moment = require('moment') | |
var mkdirp = require('mkdirp') | |
var debug = require('debug')('gilmarkgifs') | |
function generateGifForEachSubtitle (filePath) { | |
var identifier = getSeasonEpisodeIdentifierFromFilePath(filePath) | |
debug('Generating GIFs for Gilmore Girls ' + identifier) | |
extractSubtitlesFromFile(filePath, function (err, subtitles) { | |
var destFolder = path.join(__dirname, 'data', 'frames', identifier) | |
mkdirp.sync(destFolder) | |
var parsedSubtitles = subtitlesParser.fromSrt(subtitles) | |
parsedSubtitles.forEach(function (subtitleData) { | |
var timestampMs = convertTimeToTimestamp(subtitleData.endTime) - convertTimeToTimestamp(subtitleData.startTime) | |
subtitleData.duration = convertTimestampToTime(timestampMs) | |
var gifPath = generateGifForSubtitle(filePath, subtitleData, destFolder) | |
addSubtitleToGif(filePath, gifPath, subtitleData) | |
}) | |
}) | |
} | |
function generateGifForSubtitle (filePath, subtitleData, destFolder) { | |
debug('Generate frames GIF for subtitle #' + subtitleData.id) | |
var scriptPath = path.join(__dirname, 'script', 'extract-gif') | |
var destPath = path.join(destFolder, subtitleData.id + '.gif') | |
var identifier = getSeasonEpisodeIdentifierFromFilePath(filePath) | |
var cmd = [ | |
'bash', | |
scriptPath, | |
filePath, | |
destPath, | |
subtitleData.startTime.replace(',','.'), | |
subtitleData.duration.replace(',','.') | |
].join(' ') | |
childProcess.execSync(cmd) | |
debug('Saved frames GIF to ' + destPath) | |
return destPath | |
} | |
function addSubtitleToGif (filePath, gifPath, subtitleData) { | |
var identifier = getSeasonEpisodeIdentifierFromFilePath(filePath) | |
var destFolder = path.join(__dirname, 'data', 'annotated', identifier) | |
var destPath = path.join(destFolder, subtitleData.id + '.gif') | |
debug('Generate annoted GIF for subtitle #' + subtitleData.id) | |
mkdirp.sync(destFolder) | |
var subtitleText = '"' + subtitleData.text.replace(/"/g, "'") + '"' | |
var cmd = [ | |
'convert', | |
gifPath, | |
'-gravity south', | |
'-font Helvetica', | |
'-pointsize 14', | |
'-stroke \'#000C\'', | |
'-strokewidth 3', | |
'-annotate 0', | |
subtitleText, | |
'-stroke none', | |
'-fill white', | |
'-annotate 0', | |
subtitleText, | |
destPath | |
].join(' ') | |
childProcess.execSync(cmd) | |
debug('Saved annoted GIF to ' + destPath) | |
} | |
function convertTimeToTimestamp (time) { | |
return moment.utc(time, "HH:mm:ss,SSS").set({'year':1970, 'month':0, 'date':1}).valueOf() | |
} | |
function convertTimestampToTime (timestamp) { | |
return moment.utc(timestamp, 'x').format("HH:mm:ss,SSS") | |
} | |
function extractSubtitlesFromFile (filePath, cb) { | |
var identifier = getSeasonEpisodeIdentifierFromFilePath(filePath) | |
var subtitleDestinationPath = path.join(__dirname, 'data', 'subtitles', identifier + '.srt') | |
getMkvInfo(filePath, function(err, info) { | |
var subtitleExtractId = getExtractIdForSubtitleTrack(info) | |
var cmd = [ | |
'mkvextract', | |
'tracks', | |
filePath, | |
subtitleExtractId + ':' + subtitleDestinationPath | |
].join(' ') | |
childProcess.exec(cmd, function (err, output) { | |
if (err) throw new Error('Failed to extract subtitles') | |
var subtitles = fs.readFileSync(subtitleDestinationPath, 'utf8') | |
cb(null, subtitles) | |
}) | |
}) | |
} | |
function getSeasonEpisodeIdentifierFromFilePath (filePath) { | |
return filePath.match(/S\d+E\d+/)[0] | |
} | |
function getMkvInfo (filePath, cb) { | |
childProcess.exec('mkvinfo ' + filePath, function(err, info) { | |
if (err) throw new Error('Could not get info for file') | |
cb(null, info) | |
}) | |
} | |
function getExtractIdForSubtitleTrack (mkvinfoOutput) { | |
var arr = mkvinfoOutput.split('\n') | |
var typeLine = arr.indexOf('| + Track type: subtitles') | |
if (!typeLine) throw new Error('Could not find subtitle track type') | |
var targetLine = typeLine - 2 | |
var id = arr[targetLine].match(/mkvextract: (\d)/)[1] | |
return parseInt(id) | |
} | |
module.exports = generateGifForEachSubtitle |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment