mpv2oboeru

mpv helpers to create flashcards from movies and TV shows
git clone anongit@rnpnr.xyz:mpv2oboeru.git
Log | Files | Refs | Feed | README | LICENSE

Commit: 39d9c598e7539698a71262e40743bcfa896da51d
Parent: 27f0b567d61a04d54b6b0db9ad7e3aa31e3bbbe9
Author: Ren Tatsumoto
Date:   Sun, 24 Oct 2021 14:41:41 +0300

bring back ffmpeg encoder

for those users who can't obtain an mpv build with the encoder built-in

Diffstat:
Mencoder.lua | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msubs2srs.lua | 1+
2 files changed, 100 insertions(+), 17 deletions(-)

diff --git a/encoder.lua b/encoder.lua @@ -1,6 +1,10 @@ local mp = require('mp') local utils = require('mp.utils') local _config, _store_fn, _os_temp_dir, _subprocess +local encoder + +------------------------------------------------------------ +-- utility functions local pad_timings = function(padding, start_time, end_time) local video_duration = mp.get_property_number('duration') @@ -28,11 +32,73 @@ local get_active_track = function(track_type) return nil end -local create_snapshot = function(timestamp, filename) - local source_path = mp.get_property("path") - local output_path = utils.join_path(_os_temp_dir(), filename) +------------------------------------------------------------ +-- ffmpeg encoder + +local ffmpeg = {} + +ffmpeg.prefix = { "ffmpeg", "-hide_banner", "-nostdin", "-y", "-loglevel", "quiet", "-sn", } + +ffmpeg.prepend = function(args) + if next(args) ~= nil then + for i, value in ipairs(ffmpeg.prefix) do + table.insert(args, i, value) + end + end + return args +end + +ffmpeg.make_snapshot_args = function(source_path, output_path, timestamp) + return ffmpeg.prepend { + '-an', + '-ss', tostring(timestamp), + '-i', source_path, + '-map_metadata', '-1', + '-vcodec', _config.snapshot_codec, + '-lossless', '0', + '-compression_level', '6', + '-qscale:v', tostring(_config.snapshot_quality), + '-vf', string.format('scale=%d:%d', _config.snapshot_width, _config.snapshot_height), + '-vframes', '1', + output_path + } +end + +ffmpeg.make_audio_args = function(source_path, output_path, start_timestamp, end_timestamp) + local audio_track = get_active_track('audio') + local audio_track_id = audio_track['ff-index'] - local args = { + if audio_track and audio_track.external == true then + source_path = audio_track['external-filename'] + audio_track_id = 'a' + end + + return ffmpeg.prepend { + '-vn', + '-ss', tostring(start_timestamp), + '-to', tostring(end_timestamp), + '-i', source_path, + '-map_metadata', '-1', + '-map', string.format("0:%d", audio_track_id), + '-ac', '1', + '-codec:a', _config.audio_codec, + '-vbr', 'on', + '-compression_level', '10', + '-application', 'voip', + '-b:a', tostring(_config.audio_bitrate), + '-filter:a', string.format("volume=%.1f", _config.tie_volumes and mp.get_property_native('volume') / 100 or 1), + '-af', 'silenceremove=1:0:-50dB', + output_path + } +end + +------------------------------------------------------------ +-- mpv encoder + +local mpv = {} + +mpv.make_snapshot_args = function(source_path, output_path, timestamp) + return { 'mpv', source_path, '--loop-file=no', @@ -48,29 +114,18 @@ local create_snapshot = function(timestamp, filename) table.concat { '--vf-add=scale=', _config.snapshot_width, ':', _config.snapshot_height }, table.concat { '-o=', output_path } } - local on_finish = function() - _store_fn(filename, output_path) - os.remove(output_path) - end - _subprocess(args, on_finish) end -local create_audio = function(start_timestamp, end_timestamp, filename, padding) - local source_path = mp.get_property("path") +mpv.make_audio_args = function(source_path, output_path, start_timestamp, end_timestamp) local audio_track = get_active_track('audio') local audio_track_id = mp.get_property("aid") - local output_path = utils.join_path(_os_temp_dir(), filename) if audio_track and audio_track.external == true then source_path = audio_track['external-filename'] audio_track_id = 'auto' end - if padding > 0 then - start_timestamp, end_timestamp = pad_timings(padding, start_timestamp, end_timestamp) - end - - local args = { + return { 'mpv', source_path, '--loop-file=no', @@ -81,6 +136,7 @@ local create_audio = function(start_timestamp, end_timestamp, filename, padding) '--oacopts-add=vbr=on', '--oacopts-add=application=voip', '--oacopts-add=compression_level=10', + '--af-append=silenceremove=1:0:-50dB', table.concat { '--oac=', _config.audio_codec }, table.concat { '--start=', start_timestamp }, table.concat { '--end=', end_timestamp }, @@ -89,6 +145,31 @@ local create_audio = function(start_timestamp, end_timestamp, filename, padding) table.concat { '--oacopts-add=b=', _config.audio_bitrate }, table.concat { '-o=', output_path } } +end + +------------------------------------------------------------ +-- main interface + +local create_snapshot = function(timestamp, filename) + local source_path = mp.get_property("path") + local output_path = utils.join_path(_os_temp_dir(), filename) + local args = encoder.make_snapshot_args(source_path, output_path, timestamp) + local on_finish = function() + _store_fn(filename, output_path) + os.remove(output_path) + end + _subprocess(args, on_finish) +end + +local create_audio = function(start_timestamp, end_timestamp, filename, padding) + local source_path = mp.get_property("path") + local output_path = utils.join_path(_os_temp_dir(), filename) + + if padding > 0 then + start_timestamp, end_timestamp = pad_timings(padding, start_timestamp, end_timestamp) + end + + local args = encoder.make_audio_args(source_path, output_path, start_timestamp, end_timestamp) local on_finish = function() _store_fn(filename, output_path) os.remove(output_path) @@ -101,6 +182,7 @@ local init = function(config, store_fn, os_temp_dir, subprocess) _store_fn = store_fn _os_temp_dir = os_temp_dir _subprocess = subprocess + encoder = config.use_ffmpeg and ffmpeg or mpv end return { diff --git a/subs2srs.lua b/subs2srs.lua @@ -40,6 +40,7 @@ local config = { autoclip = false, -- enable copying subs to the clipboard when mpv starts nuke_spaces = true, -- remove all spaces from exported anki cards clipboard_trim_enabled = true, -- remove unnecessary characters from strings before copying to the clipboard + use_ffmpeg = false, -- if set to true, use ffmpeg to create audio clips and snapshots. by default use mpv. snapshot_format = "webp", -- webp or jpg snapshot_quality = 15, -- from 0=lowest to 100=highest snapshot_width = -2, -- a positive integer or -2 for auto