Skip to content

Instantly share code, notes, and snippets.

@karlbright
Created March 16, 2016 13:05
Show Gist options
  • Save karlbright/dcddaa42cf8f3337a596 to your computer and use it in GitHub Desktop.
Save karlbright/dcddaa42cf8f3337a596 to your computer and use it in GitHub Desktop.
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