diff options
Diffstat (limited to 'youtube_dl/postprocessor/ffmpeg.py')
| -rw-r--r-- | youtube_dl/postprocessor/ffmpeg.py | 115 | 
1 files changed, 61 insertions, 54 deletions
diff --git a/youtube_dl/postprocessor/ffmpeg.py b/youtube_dl/postprocessor/ffmpeg.py index 06b8c0548..1881f4849 100644 --- a/youtube_dl/postprocessor/ffmpeg.py +++ b/youtube_dl/postprocessor/ffmpeg.py @@ -139,6 +139,30 @@ class FFmpegPostProcessor(PostProcessor):      def probe_executable(self):          return self._paths[self.probe_basename] +    def get_audio_codec(self, path): +        if not self.probe_available: +            raise PostProcessingError('ffprobe or avprobe not found. Please install one.') +        try: +            cmd = [ +                encodeFilename(self.probe_executable, True), +                encodeArgument('-show_streams'), +                encodeFilename(self._ffmpeg_filename_argument(path), True)] +            if self._downloader.params.get('verbose', False): +                self._downloader.to_screen('[debug] %s command line: %s' % (self.basename, shell_quote(cmd))) +            handle = subprocess.Popen(cmd, stderr=compat_subprocess_get_DEVNULL(), stdout=subprocess.PIPE, stdin=subprocess.PIPE) +            output = handle.communicate()[0] +            if handle.wait() != 0: +                return None +        except (IOError, OSError): +            return None +        audio_codec = None +        for line in output.decode('ascii', 'ignore').split('\n'): +            if line.startswith('codec_name='): +                audio_codec = line.split('=')[1].strip() +            elif line.strip() == 'codec_type=audio' and audio_codec is not None: +                return audio_codec +        return None +      def run_ffmpeg_multiple_files(self, input_paths, out_path, opts):          self.check_version() @@ -175,7 +199,8 @@ class FFmpegPostProcessor(PostProcessor):          # Always use 'file:' because the filename may contain ':' (ffmpeg          # interprets that as a protocol) or can start with '-' (-- is broken in          # ffmpeg, see https://ffmpeg.org/trac/ffmpeg/ticket/2127 for details) -        return 'file:' + fn +        # Also leave '-' intact in order not to break streaming to stdout. +        return 'file:' + fn if fn != '-' else fn  class FFmpegExtractAudioPP(FFmpegPostProcessor): @@ -187,31 +212,6 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor):          self._preferredquality = preferredquality          self._nopostoverwrites = nopostoverwrites -    def get_audio_codec(self, path): - -        if not self.probe_available: -            raise PostProcessingError('ffprobe or avprobe not found. Please install one.') -        try: -            cmd = [ -                encodeFilename(self.probe_executable, True), -                encodeArgument('-show_streams'), -                encodeFilename(self._ffmpeg_filename_argument(path), True)] -            if self._downloader.params.get('verbose', False): -                self._downloader.to_screen('[debug] %s command line: %s' % (self.basename, shell_quote(cmd))) -            handle = subprocess.Popen(cmd, stderr=compat_subprocess_get_DEVNULL(), stdout=subprocess.PIPE, stdin=subprocess.PIPE) -            output = handle.communicate()[0] -            if handle.wait() != 0: -                return None -        except (IOError, OSError): -            return None -        audio_codec = None -        for line in output.decode('ascii', 'ignore').split('\n'): -            if line.startswith('codec_name='): -                audio_codec = line.split('=')[1].strip() -            elif line.strip() == 'codec_type=audio' and audio_codec is not None: -                return audio_codec -        return None -      def run_ffmpeg(self, path, out_path, codec, more_opts):          if codec is None:              acodec_opts = [] @@ -279,6 +279,9 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor):          prefix, sep, ext = path.rpartition('.')  # not os.path.splitext, since the latter does not work on unicode in all setups          new_path = prefix + sep + extension +        information['filepath'] = new_path +        information['ext'] = extension +          # If we download foo.mp3 and convert it to... foo.mp3, then don't delete foo.mp3, silly.          if (new_path == path or                  (self._nopostoverwrites and os.path.exists(encodeFilename(new_path)))): @@ -300,9 +303,6 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor):                  new_path, time.time(), information['filetime'],                  errnote='Cannot update utime of audio file') -        information['filepath'] = new_path -        information['ext'] = extension -          return [path], information @@ -388,23 +388,30 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):  class FFmpegMetadataPP(FFmpegPostProcessor):      def run(self, info):          metadata = {} -        if info.get('title') is not None: -            metadata['title'] = info['title'] -        if info.get('upload_date') is not None: -            metadata['date'] = info['upload_date'] -        if info.get('artist') is not None: -            metadata['artist'] = info['artist'] -        elif info.get('uploader') is not None: -            metadata['artist'] = info['uploader'] -        elif info.get('uploader_id') is not None: -            metadata['artist'] = info['uploader_id'] -        if info.get('description') is not None: -            metadata['description'] = info['description'] -            metadata['comment'] = info['description'] -        if info.get('webpage_url') is not None: -            metadata['purl'] = info['webpage_url'] -        if info.get('album') is not None: -            metadata['album'] = info['album'] + +        def add(meta_list, info_list=None): +            if not info_list: +                info_list = meta_list +            if not isinstance(meta_list, (list, tuple)): +                meta_list = (meta_list,) +            if not isinstance(info_list, (list, tuple)): +                info_list = (info_list,) +            for info_f in info_list: +                if info.get(info_f) is not None: +                    for meta_f in meta_list: +                        metadata[meta_f] = info[info_f] +                    break + +        add('title', ('track', 'title')) +        add('date', 'upload_date') +        add(('description', 'comment'), 'description') +        add('purl', 'webpage_url') +        add('track', 'track_number') +        add('artist', ('artist', 'creator', 'uploader', 'uploader_id')) +        add('genre') +        add('album') +        add('album_artist') +        add('disc', 'disc_number')          if not metadata:              self._downloader.to_screen('[ffmpeg] There isn\'t any metadata to add') @@ -496,15 +503,15 @@ class FFmpegFixupM4aPP(FFmpegPostProcessor):  class FFmpegFixupM3u8PP(FFmpegPostProcessor):      def run(self, info):          filename = info['filepath'] -        temp_filename = prepend_extension(filename, 'temp') +        if self.get_audio_codec(filename) == 'aac': +            temp_filename = prepend_extension(filename, 'temp') -        options = ['-c', 'copy', '-f', 'mp4', '-bsf:a', 'aac_adtstoasc'] -        self._downloader.to_screen('[ffmpeg] Fixing malformated aac bitstream in "%s"' % filename) -        self.run_ffmpeg(filename, temp_filename, options) - -        os.remove(encodeFilename(filename)) -        os.rename(encodeFilename(temp_filename), encodeFilename(filename)) +            options = ['-c', 'copy', '-f', 'mp4', '-bsf:a', 'aac_adtstoasc'] +            self._downloader.to_screen('[ffmpeg] Fixing malformated aac bitstream in "%s"' % filename) +            self.run_ffmpeg(filename, temp_filename, options) +            os.remove(encodeFilename(filename)) +            os.rename(encodeFilename(temp_filename), encodeFilename(filename))          return [], info @@ -536,7 +543,7 @@ class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor):              sub_filenames.append(old_file)              new_file = subtitles_filename(filename, lang, new_ext) -            if ext == 'dfxp' or ext == 'ttml': +            if ext == 'dfxp' or ext == 'ttml' or ext == 'tt':                  self._downloader.report_warning(                      'You have requested to convert dfxp (TTML) subtitles into another format, '                      'which results in style information loss')  | 
