mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-30 12:01:28 +00:00
[FFmpegMetadata] Add language of each stream
and some refactoring
This commit is contained in:
parent
6606817a86
commit
7dde84f3c9
|
@ -1,6 +1,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import io
|
import io
|
||||||
|
import itertools
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
@ -243,7 +244,7 @@ def real_run_ffmpeg(self, input_path_opts, output_path_opts):
|
||||||
self.check_version()
|
self.check_version()
|
||||||
|
|
||||||
oldest_mtime = min(
|
oldest_mtime = min(
|
||||||
os.stat(encodeFilename(path)).st_mtime for path, _ in input_path_opts)
|
os.stat(encodeFilename(path)).st_mtime for path, _ in input_path_opts if path)
|
||||||
|
|
||||||
cmd = [encodeFilename(self.executable, True), encodeArgument('-y')]
|
cmd = [encodeFilename(self.executable, True), encodeArgument('-y')]
|
||||||
# avconv does not have repeat option
|
# avconv does not have repeat option
|
||||||
|
@ -262,8 +263,9 @@ def make_args(file, args, name, number):
|
||||||
+ [encodeFilename(self._ffmpeg_filename_argument(file), True)])
|
+ [encodeFilename(self._ffmpeg_filename_argument(file), True)])
|
||||||
|
|
||||||
for arg_type, path_opts in (('i', input_path_opts), ('o', output_path_opts)):
|
for arg_type, path_opts in (('i', input_path_opts), ('o', output_path_opts)):
|
||||||
cmd += [arg for i, o in enumerate(path_opts)
|
cmd += itertools.chain.from_iterable(
|
||||||
for arg in make_args(o[0], o[1], arg_type, i + 1)]
|
make_args(path, list(opts), arg_type, i + 1)
|
||||||
|
for i, (path, opts) in enumerate(path_opts) if path)
|
||||||
|
|
||||||
self.write_debug('ffmpeg command line: %s' % shell_quote(cmd))
|
self.write_debug('ffmpeg command line: %s' % shell_quote(cmd))
|
||||||
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
|
||||||
|
@ -274,7 +276,8 @@ def make_args(file, args, name, number):
|
||||||
self.report_error(stderr)
|
self.report_error(stderr)
|
||||||
raise FFmpegPostProcessorError(stderr.split('\n')[-1])
|
raise FFmpegPostProcessorError(stderr.split('\n')[-1])
|
||||||
for out_path, _ in output_path_opts:
|
for out_path, _ in output_path_opts:
|
||||||
self.try_utime(out_path, oldest_mtime, oldest_mtime)
|
if out_path:
|
||||||
|
self.try_utime(out_path, oldest_mtime, oldest_mtime)
|
||||||
return stderr.decode('utf-8', 'replace')
|
return stderr.decode('utf-8', 'replace')
|
||||||
|
|
||||||
def run_ffmpeg(self, path, out_path, opts):
|
def run_ffmpeg(self, path, out_path, opts):
|
||||||
|
@ -527,6 +530,15 @@ def run(self, information):
|
||||||
|
|
||||||
|
|
||||||
class FFmpegMetadataPP(FFmpegPostProcessor):
|
class FFmpegMetadataPP(FFmpegPostProcessor):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _options(target_ext):
|
||||||
|
yield from ('-map', '0', '-dn')
|
||||||
|
if target_ext == 'm4a':
|
||||||
|
yield from ('-vn', '-acodec', 'copy')
|
||||||
|
else:
|
||||||
|
yield from ('-c', 'copy')
|
||||||
|
|
||||||
@PostProcessor._restrict_to(images=False)
|
@PostProcessor._restrict_to(images=False)
|
||||||
def run(self, info):
|
def run(self, info):
|
||||||
metadata = {}
|
metadata = {}
|
||||||
|
@ -565,22 +577,17 @@ def add(meta_list, info_list=None):
|
||||||
for key in filter(lambda k: k.startswith(prefix), info.keys()):
|
for key in filter(lambda k: k.startswith(prefix), info.keys()):
|
||||||
add(key[len(prefix):], key)
|
add(key[len(prefix):], key)
|
||||||
|
|
||||||
if not metadata:
|
filename, metadata_filename = info['filepath'], None
|
||||||
self.to_screen('There isn\'t any metadata to add')
|
options = [('-metadata', f'{name}={value}') for name, value in metadata.items()]
|
||||||
return [], info
|
|
||||||
|
|
||||||
filename = info['filepath']
|
stream_idx = 0
|
||||||
temp_filename = prepend_extension(filename, 'temp')
|
for fmt in info.get('requested_formats') or []:
|
||||||
in_filenames = [filename]
|
stream_count = 2 if 'none' not in (fmt.get('vcodec'), fmt.get('acodec')) else 1
|
||||||
options = ['-map', '0', '-dn']
|
if fmt.get('language'):
|
||||||
|
lang = ISO639Utils.short2long(fmt['language']) or fmt['language']
|
||||||
if info['ext'] == 'm4a':
|
options.extend(('-metadata:s:%d' % (stream_idx + i), 'language=%s' % lang)
|
||||||
options.extend(['-vn', '-acodec', 'copy'])
|
for i in range(stream_count))
|
||||||
else:
|
stream_idx += stream_count
|
||||||
options.extend(['-c', 'copy'])
|
|
||||||
|
|
||||||
for name, value in metadata.items():
|
|
||||||
options.extend(['-metadata', '%s=%s' % (name, value)])
|
|
||||||
|
|
||||||
chapters = info.get('chapters', [])
|
chapters = info.get('chapters', [])
|
||||||
if chapters:
|
if chapters:
|
||||||
|
@ -598,24 +605,29 @@ def ffmpeg_escape(text):
|
||||||
if chapter_title:
|
if chapter_title:
|
||||||
metadata_file_content += 'title=%s\n' % ffmpeg_escape(chapter_title)
|
metadata_file_content += 'title=%s\n' % ffmpeg_escape(chapter_title)
|
||||||
f.write(metadata_file_content)
|
f.write(metadata_file_content)
|
||||||
in_filenames.append(metadata_filename)
|
options.append(('-map_metadata', '1'))
|
||||||
options.extend(['-map_metadata', '1'])
|
|
||||||
|
|
||||||
if ('no-attach-info-json' not in self.get_param('compat_opts', [])
|
if ('no-attach-info-json' not in self.get_param('compat_opts', [])
|
||||||
and '__infojson_filename' in info and info['ext'] in ('mkv', 'mka')):
|
and '__infojson_filename' in info and info['ext'] in ('mkv', 'mka')):
|
||||||
old_stream, new_stream = self.get_stream_number(
|
old_stream, new_stream = self.get_stream_number(filename, ('tags', 'mimetype'), 'application/json')
|
||||||
filename, ('tags', 'mimetype'), 'application/json')
|
|
||||||
if old_stream is not None:
|
if old_stream is not None:
|
||||||
options.extend(['-map', '-0:%d' % old_stream])
|
options.append(('-map', '-0:%d' % old_stream))
|
||||||
new_stream -= 1
|
new_stream -= 1
|
||||||
|
|
||||||
options.extend([
|
options.append((
|
||||||
'-attach', info['__infojson_filename'],
|
'-attach', info['__infojson_filename'],
|
||||||
'-metadata:s:%d' % new_stream, 'mimetype=application/json'
|
'-metadata:s:%d' % new_stream, 'mimetype=application/json'
|
||||||
])
|
))
|
||||||
|
|
||||||
self.to_screen('Adding metadata to \'%s\'' % filename)
|
if not options:
|
||||||
self.run_ffmpeg_multiple_files(in_filenames, temp_filename, options)
|
self.to_screen('There isn\'t any metadata to add')
|
||||||
|
return [], info
|
||||||
|
|
||||||
|
temp_filename = prepend_extension(filename, 'temp')
|
||||||
|
self.to_screen('Adding metadata to "%s"' % filename)
|
||||||
|
self.run_ffmpeg_multiple_files(
|
||||||
|
(filename, metadata_filename), temp_filename,
|
||||||
|
itertools.chain(self._options(info['ext']), *options))
|
||||||
if chapters:
|
if chapters:
|
||||||
os.remove(metadata_filename)
|
os.remove(metadata_filename)
|
||||||
os.remove(encodeFilename(filename))
|
os.remove(encodeFilename(filename))
|
||||||
|
|
Loading…
Reference in a new issue