Merge branch 'atomicparsley' (closes #2436)
authorJaime Marquínez Ferrándiz <jaime.marquinez.ferrandiz@gmail.com>
Sat, 12 Apr 2014 13:52:42 +0000 (15:52 +0200)
committerJaime Marquínez Ferrándiz <jaime.marquinez.ferrandiz@gmail.com>
Sat, 12 Apr 2014 13:52:42 +0000 (15:52 +0200)
1  2 
youtube_dl/__init__.py
youtube_dl/postprocessor/ffmpeg.py

diff --combined youtube_dl/__init__.py
index 7e504b75c0554841d857941802475d63c846046a,4f4ec3871f1445cfee7a2ce16954913e1d9aea8d..42ef13786bf2e9c228f02b6f4568270d682fd57d
@@@ -51,8 -51,6 +51,8 @@@ __authors__  = 
      'David Wagner',
      'Juan C. Olivares',
      'Mattias Harrysson',
 +    'phaer',
 +    'Sainyam Kapoor',
  )
  
  __license__ = 'Public Domain'
@@@ -92,6 -90,8 +92,8 @@@ from .extractor import gen_extractor
  from .version import __version__
  from .YoutubeDL import YoutubeDL
  from .postprocessor import (
+     AtomicParsleyPP,
+     FFmpegAudioFixPP,
      FFmpegMetadataPP,
      FFmpegVideoConvertor,
      FFmpegExtractAudioPP,
@@@ -243,7 -243,7 +245,7 @@@ def parseOpts(overrideArguments=None)
          help='Use the specified HTTP/HTTPS proxy. Pass in an empty string (--proxy "") for direct connection')
      general.add_option('--no-check-certificate', action='store_true', dest='no_check_certificate', default=False, help='Suppress HTTPS certificate validation.')
      general.add_option(
 -        '--prefer-insecure', action='store_true', dest='prefer_insecure',
 +        '--prefer-insecure', '--prefer-unsecure', action='store_true', dest='prefer_insecure',
          help='Use an unencrypted connection to retrieve information about the video. (Currently supported only for YouTube)')
      general.add_option(
          '--cache-dir', dest='cachedir', default=get_cachedir(), metavar='DIR',
      general.add_option(
          '--bidi-workaround', dest='bidi_workaround', action='store_true',
          help=u'Work around terminals that lack bidirectional text support. Requires bidiv or fribidi executable in PATH')
 -    general.add_option('--default-search',
 -            dest='default_search', metavar='PREFIX',
 -            help='Use this prefix for unqualified URLs. For example "gvsearch2:" downloads two videos from google videos for  youtube-dl "large apple". By default (with value "auto") youtube-dl guesses.')
 +    general.add_option(
 +        '--default-search',
 +        dest='default_search', metavar='PREFIX',
 +        help='Use this prefix for unqualified URLs. For example "gvsearch2:" downloads two videos from google videos for  youtube-dl "large apple". By default (with value "auto") youtube-dl guesses.')
      general.add_option(
          '--ignore-config',
          action='store_true',
          help='Do not read configuration files. When given in the global configuration file /etc/youtube-dl.conf: do not read the user configuration in ~/.config/youtube-dl.conf (%APPDATA%/youtube-dl/config.txt on Windows)')
 +    general.add_option(
 +        '--encoding', dest='encoding', metavar='ENCODING',
 +        help='Force the specified encoding (experimental)')
  
      selection.add_option(
          '--playlist-start',
              help='simulate, quiet but print output format', default=False)
      verbosity.add_option('-j', '--dump-json',
              action='store_true', dest='dumpjson',
 -            help='simulate, quiet but print JSON information', default=False)
 +            help='simulate, quiet but print JSON information. See --output for a description of available keys.', default=False)
      verbosity.add_option('--newline',
              action='store_true', dest='progress_with_newline', help='output progress bar as new lines', default=False)
      verbosity.add_option('--no-progress',
              help='do not overwrite post-processed files; the post-processed files are overwritten by default')
      postproc.add_option('--embed-subs', action='store_true', dest='embedsubtitles', default=False,
              help='embed subtitles in the video (only for mp4 videos)')
+     postproc.add_option('--embed-thumbnail', action='store_true', dest='embedthumbnail', default=False,
+             help='embed thumbnail in the audio as cover art')
      postproc.add_option('--add-metadata', action='store_true', dest='addmetadata', default=False,
              help='write metadata to the video file')
      postproc.add_option('--xattrs', action='store_true', dest='xattrs', default=False,
              write_string(u'[debug] System config: ' + repr(_hide_login_info(systemConf)) + '\n')
              write_string(u'[debug] User config: ' + repr(_hide_login_info(userConf)) + '\n')
              write_string(u'[debug] Command-line args: ' + repr(_hide_login_info(commandLineConf)) + '\n')
 -            write_string(u'[debug] Encodings: locale %r, fs %r, out %r, pref: %r\n' %
 -                         (locale.getpreferredencoding(), sys.getfilesystemencoding(), sys.stdout.encoding, preferredencoding()))
  
      return parser, opts, args
  
@@@ -678,7 -678,7 +682,7 @@@ def _real_main(argv=None)
          date = DateRange.day(opts.date)
      else:
          date = DateRange(opts.dateafter, opts.datebefore)
 -    if opts.default_search not in ('auto', None) and ':' not in opts.default_search:
 +    if opts.default_search not in ('auto', 'auto_warning', None) and ':' not in opts.default_search:
          parser.error(u'--default-search invalid; did you forget a colon (:) at the end?')
  
      # Do not download videos when there are audio-only formats
          'include_ads': opts.include_ads,
          'default_search': opts.default_search,
          'youtube_include_dash_manifest': opts.youtube_include_dash_manifest,
 +        'encoding': opts.encoding,
      }
  
      with YoutubeDL(ydl_opts) as ydl:
              ydl.add_post_processor(FFmpegEmbedSubtitlePP(subtitlesformat=opts.subtitlesformat))
          if opts.xattrs:
              ydl.add_post_processor(XAttrMetadataPP())
+         if opts.embedthumbnail:
+             if not opts.addmetadata:
+                 ydl.add_post_processor(FFmpegAudioFixPP())
+             ydl.add_post_processor(AtomicParsleyPP())
  
          # Update version
          if opts.update_self:
index 8922920cd03b35a94701677173609153fb1f7aa2,d5b71b96f8322181137ef4da5bc0ef9eba1a294f..602e370f417f3d6f238ce6c7309330680321b795
@@@ -54,7 -54,7 +54,7 @@@ class FFmpegPostProcessor(PostProcessor
          if self._downloader.params.get('verbose', False):
              self._downloader.to_screen(u'[debug] ffmpeg command line: %s' % shell_quote(cmd))
          p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 -        stdout,stderr = p.communicate()
 +        stdout, stderr = p.communicate()
          if p.returncode != 0:
              stderr = stderr.decode('utf-8', 'replace')
              msg = stderr.strip().split('\n')[-1]
@@@ -464,7 -464,11 +464,11 @@@ class FFmpegMetadataPP(FFmpegPostProces
          filename = info['filepath']
          temp_filename = prepend_extension(filename, 'temp')
  
-         options = ['-c', 'copy']
+         if info['ext'] == u'm4a':
+             options = ['-vn', '-acodec', 'copy']
+         else:
+             options = ['-c', 'copy']
          for (name, value) in metadata.items():
              options.extend(['-metadata', '%s=%s' % (name, value)])
  
@@@ -483,3 -487,17 +487,17 @@@ class FFmpegMergerPP(FFmpegPostProcesso
          self.run_ffmpeg_multiple_files(info['__files_to_merge'], filename, args)
          return True, info
  
+ class FFmpegAudioFixPP(FFmpegPostProcessor):
+     def run(self, info):
+         filename = info['filepath']
+         temp_filename = prepend_extension(filename, 'temp')
+         options = ['-vn', '-acodec', 'copy']
+         self._downloader.to_screen(u'[ffmpeg] Fixing audio file "%s"' % filename)
+         self.run_ffmpeg(filename, temp_filename, options)
+         os.remove(encodeFilename(filename))
+         os.rename(encodeFilename(temp_filename), encodeFilename(filename))
+         return True, info