Audio thumbnailing & spectrograms, media plugins use sniffing
[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
a63b640f 19import os
93bdab9d 20
93bdab9d 21from mediagoblin import mg_globals as mgg
8e5f9746
JW
22from mediagoblin.processing import mark_entry_failed, \
23 THUMB_SIZE, MEDIUM_SIZE, create_pub_filepath
26729e02 24from . import transcoders
1f255101 25
1f255101 26logging.basicConfig()
8e5f9746
JW
27
28_log = logging.getLogger(__name__)
29_log.setLevel(logging.DEBUG)
93bdab9d 30
ec4261a4 31def sniff_handler(media_file, **kw):
10085b77
JW
32 transcoder = transcoders.VideoTranscoder()
33 try:
34 data = transcoder.discover(media_file.name)
35
36 _log.debug('Discovered: {0}'.format(data.__dict__))
37
38 if data.is_video == True:
39 return True
40 except:
41 _log.error('Exception caught when trying to discover {0}'.format(
42 kw.get('media')))
43
ec4261a4 44 return False
93bdab9d
JW
45
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')
59
e9c1b938 60 medium_filepath = create_pub_filepath(
a63b640f
JW
61 entry,
62 '{original}-640p.webm'.format(
63 original=os.path.splitext(
5a34a80d 64 queued_filepath[-1])[0] # Select the file name without .ext
a63b640f 65 ))
93bdab9d 66
e9c1b938
JW
67 thumbnail_filepath = create_pub_filepath(
68 entry, 'thumbnail.jpg')
1f255101 69
93bdab9d 70
e9c1b938
JW
71 # Create a temporary file for the video destination
72 tmp_dst = tempfile.NamedTemporaryFile()
93bdab9d 73
e9c1b938
JW
74 with tmp_dst:
75 # Transcode queued file to a VP8/vorbis file that fits in a 640x640 square
10085b77
JW
76 transcoder = transcoders.VideoTranscoder()
77 transcoder.transcode(queued_filename, tmp_dst.name)
93bdab9d 78
e9c1b938 79 # Push transcoded video to public storage
8e5f9746 80 _log.debug('Saving medium...')
e9c1b938
JW
81 mgg.public_store.get_file(medium_filepath, 'wb').write(
82 tmp_dst.read())
8e5f9746 83 _log.debug('Saved medium')
e9c1b938 84
228c4470 85 entry.media_files['webm_640'] = medium_filepath
e9c1b938
JW
86
87 # Save the width and height of the transcoded video
ddc1cae9 88 entry.media_data['video'] = {
e9c1b938
JW
89 u'width': transcoder.dst_data.videowidth,
90 u'height': transcoder.dst_data.videoheight}
93bdab9d 91
e9c1b938
JW
92 # Create a temporary file for the video thumbnail
93 tmp_thumb = tempfile.NamedTemporaryFile()
93bdab9d 94
e9c1b938
JW
95 with tmp_thumb:
96 # Create a thumbnail.jpg that fits in a 180x180 square
97 transcoders.VideoThumbnailer(queued_filename, tmp_thumb.name)
1f255101 98
e9c1b938 99 # Push the thumbnail to public storage
8e5f9746 100 _log.debug('Saving thumbnail...')
e9c1b938
JW
101 mgg.public_store.get_file(thumbnail_filepath, 'wb').write(
102 tmp_thumb.read())
8e5f9746 103 _log.debug('Saved thumbnail')
93bdab9d 104
228c4470 105 entry.media_files['thumb'] = thumbnail_filepath
93bdab9d 106
23caf305
CAW
107 if video_config['keep_original']:
108 # Push original file to public storage
109 queued_file = file(queued_filename, 'rb')
93bdab9d 110
23caf305
CAW
111 with queued_file:
112 original_filepath = create_pub_filepath(
113 entry,
114 queued_filepath[-1])
26729e02 115
23caf305
CAW
116 with mgg.public_store.get_file(original_filepath, 'wb') as \
117 original_file:
118 _log.debug('Saving original...')
119 original_file.write(queued_file.read())
120 _log.debug('Saved original')
1f255101 121
228c4470 122 entry.media_files['original'] = original_filepath
93bdab9d 123
e9c1b938
JW
124 mgg.queue_store.delete_file(queued_filepath)
125
e9c1b938
JW
126 # Save the MediaEntry
127 entry.save()