Merge branch 'stable'
[mediagoblin.git] / mediagoblin / tests / test_audio.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2013 MediaGoblin contributors. See AUTHORS.
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
17 import tempfile
18 import shutil
19 import os
20 import pytest
21 from contextlib import contextmanager
22 import logging
23 import imghdr
24
25 #os.environ['GST_DEBUG'] = '4,python:4'
26
27 pytest.importorskip("gi.repository.Gst")
28 pytest.importorskip("scikits.audiolab")
29 import gi
30 gi.require_version('Gst', '1.0')
31 from gi.repository import Gst
32 Gst.init(None)
33
34 from mediagoblin.media_types.audio.transcoders import (AudioTranscoder,
35 AudioThumbnailer)
36 from mediagoblin.media_types.tools import discover
37
38
39 @contextmanager
40 def create_audio():
41 audio = tempfile.NamedTemporaryFile()
42 src = Gst.ElementFactory.make('audiotestsrc', None)
43 src.set_property('num-buffers', 50)
44 enc = Gst.ElementFactory.make('flacenc', None)
45 dst = Gst.ElementFactory.make('filesink', None)
46 dst.set_property('location', audio.name)
47 pipeline = Gst.Pipeline()
48 pipeline.add(src)
49 pipeline.add(enc)
50 pipeline.add(dst)
51 src.link(enc)
52 enc.link(dst)
53 pipeline.set_state(Gst.State.PLAYING)
54 state = pipeline.get_state(3 * Gst.SECOND)
55 assert state[0] == Gst.StateChangeReturn.SUCCESS
56 bus = pipeline.get_bus()
57 bus.timed_pop_filtered(
58 3 * Gst.SECOND,
59 Gst.MessageType.ERROR | Gst.MessageType.EOS)
60 pipeline.set_state(Gst.State.NULL)
61 yield (audio.name)
62
63
64 @contextmanager
65 def create_data_for_test():
66 with create_audio() as audio_name:
67 second_file = tempfile.NamedTemporaryFile()
68 yield (audio_name, second_file.name)
69
70
71 def test_transcoder():
72 '''
73 Tests AudioTransocder's transcode method
74 '''
75 transcoder = AudioTranscoder()
76 with create_data_for_test() as (audio_name, result_name):
77 transcoder.transcode(audio_name, result_name, quality=0.3,
78 progress_callback=None)
79 info = discover(result_name)
80 assert len(info.get_audio_streams()) == 1
81 transcoder.transcode(audio_name, result_name, quality=0.3,
82 mux_name='oggmux', progress_callback=None)
83 info = discover(result_name)
84 assert len(info.get_audio_streams()) == 1
85
86
87 def test_thumbnails():
88 '''Test thumbnails generation.
89
90 The code below heavily repeats
91 audio.processing.CommonAudioProcessor.create_spectrogram
92 1. Create test audio
93 2. Convert it to OGG source for spectogram using transcoder
94 3. Create spectogram in jpg
95
96 '''
97 thumbnailer = AudioThumbnailer()
98 transcoder = AudioTranscoder()
99 with create_data_for_test() as (audio_name, new_name):
100 transcoder.transcode(audio_name, new_name, mux_name='oggmux')
101 thumbnail = tempfile.NamedTemporaryFile(suffix='.jpg')
102 # fft_size below is copypasted from config_spec.ini
103 thumbnailer.spectrogram(new_name, thumbnail.name, width=100,
104 fft_size=4096)
105 assert imghdr.what(thumbnail.name) == 'jpeg'