Media processing, transcoding, display fixes
[mediagoblin.git] / mediagoblin / media_types / video / processing.py
CommitLineData
93bdab9d 1# GNU MediaGoblin -- federated, autonomous media hosting
cf29e8a8 2# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
93bdab9d
JW
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
93bdab9d 17import tempfile
e9c1b938 18import logging
93bdab9d 19
93bdab9d 20from mediagoblin import mg_globals as mgg
196a5181 21from mediagoblin.processing import \
deea3f66 22 create_pub_filepath, FilenameBuilder
26729e02 23from . import transcoders
1f255101 24
8e5f9746
JW
25_log = logging.getLogger(__name__)
26_log.setLevel(logging.DEBUG)
93bdab9d
JW
27
28
ec4261a4 29def sniff_handler(media_file, **kw):
10085b77 30 transcoder = transcoders.VideoTranscoder()
4f4f2531 31 data = transcoder.discover(media_file.name)
10085b77 32
4f4f2531 33 _log.debug('Discovered: {0}'.format(data))
10085b77 34
4f4f2531
JW
35 if not data:
36 _log.error('Could not discover {0}'.format(
10085b77 37 kw.get('media')))
4f4f2531 38 return False
26729e02 39
4f4f2531
JW
40 if data['is_video'] == True:
41 return True
26729e02 42
ec4261a4 43 return False
93bdab9d 44
c56d4b55 45
93bdab9d
JW
46def process_video(entry):
47 """
5a34a80d
JW
48 Process a video entry, transcode the queued media files (originals) and
49 create a thumbnail for the entry.
93bdab9d 50 """
23caf305
CAW
51 video_config = mgg.global_config['media_type:mediagoblin.media_types.video']
52
93bdab9d
JW
53 workbench = mgg.workbench_manager.create_workbench()
54
8545cfc9 55 queued_filepath = entry.queued_media_file
93bdab9d
JW
56 queued_filename = workbench.localized_file(
57 mgg.queue_store, queued_filepath,
58 'source')
28f364bd 59 name_builder = FilenameBuilder(queued_filename)
93bdab9d 60
e9c1b938 61 medium_filepath = create_pub_filepath(
28f364bd 62 entry, name_builder.fill('{basename}-640p.webm'))
93bdab9d 63
e9c1b938 64 thumbnail_filepath = create_pub_filepath(
28f364bd 65 entry, name_builder.fill('{basename}.thumbnail.jpg'))
93bdab9d 66
e9c1b938
JW
67 # Create a temporary file for the video destination
68 tmp_dst = tempfile.NamedTemporaryFile()
93bdab9d 69
e9c1b938
JW
70 with tmp_dst:
71 # Transcode queued file to a VP8/vorbis file that fits in a 640x640 square
10085b77 72 transcoder = transcoders.VideoTranscoder()
196a5181
JW
73 transcoder.transcode(queued_filename, tmp_dst.name,
74 vp8_quality=video_config['vp8_quality'],
75 vp8_threads=video_config['vp8_threads'],
76 vorbis_quality=video_config['vorbis_quality'])
93bdab9d 77
e9c1b938 78 # Push transcoded video to public storage
8e5f9746 79 _log.debug('Saving medium...')
e9c1b938
JW
80 mgg.public_store.get_file(medium_filepath, 'wb').write(
81 tmp_dst.read())
8e5f9746 82 _log.debug('Saved medium')
e9c1b938 83
228c4470 84 entry.media_files['webm_640'] = medium_filepath
e9c1b938
JW
85
86 # Save the width and height of the transcoded video
5ff57582
E
87 entry.media_data_init(
88 width=transcoder.dst_data.videowidth,
89 height=transcoder.dst_data.videoheight)
93bdab9d 90
e9c1b938 91 # Create a temporary file for the video thumbnail
ff3136d0 92 tmp_thumb = tempfile.NamedTemporaryFile(suffix='.jpg')
93bdab9d 93
e9c1b938
JW
94 with tmp_thumb:
95 # Create a thumbnail.jpg that fits in a 180x180 square
96 transcoders.VideoThumbnailer(queued_filename, tmp_thumb.name)
1f255101 97
e9c1b938 98 # Push the thumbnail to public storage
8e5f9746 99 _log.debug('Saving thumbnail...')
e9c1b938
JW
100 mgg.public_store.get_file(thumbnail_filepath, 'wb').write(
101 tmp_thumb.read())
8e5f9746 102 _log.debug('Saved thumbnail')
93bdab9d 103
228c4470 104 entry.media_files['thumb'] = thumbnail_filepath
93bdab9d 105
23caf305
CAW
106 if video_config['keep_original']:
107 # Push original file to public storage
108 queued_file = file(queued_filename, 'rb')
93bdab9d 109
23caf305
CAW
110 with queued_file:
111 original_filepath = create_pub_filepath(
112 entry,
113 queued_filepath[-1])
26729e02 114
23caf305
CAW
115 with mgg.public_store.get_file(original_filepath, 'wb') as \
116 original_file:
117 _log.debug('Saving original...')
118 original_file.write(queued_file.read())
119 _log.debug('Saved original')
1f255101 120
228c4470 121 entry.media_files['original'] = original_filepath
93bdab9d 122
e9c1b938
JW
123 mgg.queue_store.delete_file(queued_filepath)
124
e9c1b938
JW
125 # Save the MediaEntry
126 entry.save()