]>
Commit | Line | Data |
---|---|---|
ddbed364 | 1 | # -*- coding: utf-8 -*- |
2 | from __future__ import unicode_literals | |
3 | ||
4 | ||
5 | import os | |
6 | import subprocess | |
7 | ||
31fd9c76 | 8 | from .ffmpeg import FFmpegPostProcessor |
9 | ||
ddbed364 | 10 | from ..utils import ( |
11 | check_executable, | |
2cc6d135 | 12 | encodeArgument, |
ddbed364 | 13 | encodeFilename, |
14 | PostProcessingError, | |
15 | prepend_extension, | |
16 | shell_quote | |
17 | ) | |
18 | ||
19 | ||
20 | class EmbedThumbnailPPError(PostProcessingError): | |
21 | pass | |
22 | ||
23 | ||
31fd9c76 | 24 | class EmbedThumbnailPP(FFmpegPostProcessor): |
8e595397 YCH |
25 | def __init__(self, downloader=None, already_have_thumbnail=False): |
26 | super(EmbedThumbnailPP, self).__init__(downloader) | |
27 | self._already_have_thumbnail = already_have_thumbnail | |
28 | ||
ddbed364 | 29 | def run(self, info): |
30 | filename = info['filepath'] | |
31 | temp_filename = prepend_extension(filename, 'temp') | |
ddbed364 | 32 | |
8e595397 | 33 | if not info.get('thumbnails'): |
ddbed364 | 34 | raise EmbedThumbnailPPError('Thumbnail was not found. Nothing to do.') |
35 | ||
8e595397 | 36 | thumbnail_filename = info['thumbnails'][-1]['filename'] |
ddbed364 | 37 | |
c33a8639 YCH |
38 | if not os.path.exists(encodeFilename(thumbnail_filename)): |
39 | self._downloader.report_warning( | |
40 | 'Skipping embedding the thumbnail because the file is missing.') | |
41 | return [], info | |
42 | ||
7360db05 | 43 | if info['ext'] in ('mp3', 'mkv'): |
92995e62 | 44 | options = [ |
bb8ca1d1 | 45 | '-c', 'copy', '-map', '0', '-map', '1', |
31fd9c76 | 46 | '-metadata:s:v', 'title="Album cover"', '-metadata:s:v', 'comment="Cover (Front)"'] |
ddbed364 | 47 | |
48 | self._downloader.to_screen('[ffmpeg] Adding thumbnail to "%s"' % filename) | |
49 | ||
bb8ca1d1 | 50 | self.run_ffmpeg_multiple_files([filename, thumbnail_filename], temp_filename, options) |
ddbed364 | 51 | |
8e595397 YCH |
52 | if not self._already_have_thumbnail: |
53 | os.remove(encodeFilename(thumbnail_filename)) | |
ddbed364 | 54 | os.remove(encodeFilename(filename)) |
55 | os.rename(encodeFilename(temp_filename), encodeFilename(filename)) | |
56 | ||
d6aa68ce | 57 | elif info['ext'] in ['m4a', 'mp4']: |
ddbed364 | 58 | if not check_executable('AtomicParsley', ['-v']): |
59 | raise EmbedThumbnailPPError('AtomicParsley was not found. Please install.') | |
60 | ||
2cc6d135 YCH |
61 | cmd = [encodeFilename('AtomicParsley', True), |
62 | encodeFilename(filename, True), | |
63 | encodeArgument('--artwork'), | |
64 | encodeFilename(thumbnail_filename, True), | |
65 | encodeArgument('-o'), | |
66 | encodeFilename(temp_filename, True)] | |
ddbed364 | 67 | |
68 | self._downloader.to_screen('[atomicparsley] Adding thumbnail to "%s"' % filename) | |
69 | ||
70 | if self._downloader.params.get('verbose', False): | |
71 | self._downloader.to_screen('[debug] AtomicParsley command line: %s' % shell_quote(cmd)) | |
72 | ||
73 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
74 | stdout, stderr = p.communicate() | |
75 | ||
76 | if p.returncode != 0: | |
77 | msg = stderr.decode('utf-8', 'replace').strip() | |
78 | raise EmbedThumbnailPPError(msg) | |
79 | ||
8e595397 YCH |
80 | if not self._already_have_thumbnail: |
81 | os.remove(encodeFilename(thumbnail_filename)) | |
ddbed364 | 82 | # for formats that don't support thumbnails (like 3gp) AtomicParsley |
83 | # won't create to the temporary file | |
84 | if b'No changes' in stdout: | |
85 | self._downloader.report_warning('The file format doesn\'t support embedding a thumbnail') | |
86 | else: | |
87 | os.remove(encodeFilename(filename)) | |
88 | os.rename(encodeFilename(temp_filename), encodeFilename(filename)) | |
89 | else: | |
d6aa68ce | 90 | raise EmbedThumbnailPPError('Only mp3 and m4a/mp4 are supported for thumbnail embedding for now.') |
ddbed364 | 91 | |
92 | return [], info |