CC-5739: Added Liquidsoap playability test to airtime_analyzer
This commit is contained in:
parent
3b1c776879
commit
dbfb2fc69b
3 changed files with 100 additions and 0 deletions
|
@ -7,6 +7,7 @@ from metadata_analyzer import MetadataAnalyzer
|
||||||
from filemover_analyzer import FileMoverAnalyzer
|
from filemover_analyzer import FileMoverAnalyzer
|
||||||
from cuepoint_analyzer import CuePointAnalyzer
|
from cuepoint_analyzer import CuePointAnalyzer
|
||||||
from replaygain_analyzer import ReplayGainAnalyzer
|
from replaygain_analyzer import ReplayGainAnalyzer
|
||||||
|
from playability_analyzer import *
|
||||||
|
|
||||||
class AnalyzerPipeline:
|
class AnalyzerPipeline:
|
||||||
""" Analyzes and imports an audio file into the Airtime library.
|
""" Analyzes and imports an audio file into the Airtime library.
|
||||||
|
@ -55,6 +56,7 @@ class AnalyzerPipeline:
|
||||||
metadata = MetadataAnalyzer.analyze(audio_file_path, metadata)
|
metadata = MetadataAnalyzer.analyze(audio_file_path, metadata)
|
||||||
metadata = CuePointAnalyzer.analyze(audio_file_path, metadata)
|
metadata = CuePointAnalyzer.analyze(audio_file_path, metadata)
|
||||||
metadata = ReplayGainAnalyzer.analyze(audio_file_path, metadata)
|
metadata = ReplayGainAnalyzer.analyze(audio_file_path, metadata)
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(audio_file_path, metadata)
|
||||||
metadata = FileMoverAnalyzer.move(audio_file_path, import_directory, original_filename, metadata)
|
metadata = FileMoverAnalyzer.move(audio_file_path, import_directory, original_filename, metadata)
|
||||||
metadata["import_status"] = 0 # Successfully imported
|
metadata["import_status"] = 0 # Successfully imported
|
||||||
|
|
||||||
|
@ -64,6 +66,11 @@ class AnalyzerPipeline:
|
||||||
# Pass all the file metadata back to the main analyzer process, which then passes
|
# Pass all the file metadata back to the main analyzer process, which then passes
|
||||||
# it back to the Airtime web application.
|
# it back to the Airtime web application.
|
||||||
queue.put(metadata)
|
queue.put(metadata)
|
||||||
|
except UnplayableFileError as e:
|
||||||
|
logging.exception(e)
|
||||||
|
metadata["import_status"] = 2
|
||||||
|
metadata["reason"] = "The file could not be played."
|
||||||
|
raise e
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Ensures the traceback for this child process gets written to our log files:
|
# Ensures the traceback for this child process gets written to our log files:
|
||||||
logging.exception(e)
|
logging.exception(e)
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
__author__ = 'asantoni'
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import logging
|
||||||
|
from analyzer import Analyzer
|
||||||
|
|
||||||
|
class UnplayableFileError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class PlayabilityAnalyzer(Analyzer):
|
||||||
|
''' This class checks if a file can actually be played with Liquidsoap. '''
|
||||||
|
|
||||||
|
LIQUIDSOAP_EXECUTABLE = 'liquidsoap'
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def analyze(filename, metadata):
|
||||||
|
''' Checks if a file can be played by Liquidsoap.
|
||||||
|
:param filename: The full path to the file to analyzer
|
||||||
|
:param metadata: A metadata dictionary where the results will be put
|
||||||
|
:return: The metadata dictionary
|
||||||
|
'''
|
||||||
|
command = [PlayabilityAnalyzer.LIQUIDSOAP_EXECUTABLE, '-v', '-c', "output.dummy(audio_to_stereo(single('%s')))" % filename]
|
||||||
|
try:
|
||||||
|
subprocess.check_output(command, stderr=subprocess.STDOUT)
|
||||||
|
|
||||||
|
except OSError as e: # liquidsoap was not found
|
||||||
|
logging.warn("Failed to run: %s - %s. %s" % (command[0], e.strerror, "Do you have liquidsoap installed?"))
|
||||||
|
except (subprocess.CalledProcessError, Exception) as e: # liquidsoap returned an error code
|
||||||
|
logging.warn(e)
|
||||||
|
raise UnplayableFileError
|
||||||
|
|
||||||
|
return metadata
|
|
@ -0,0 +1,61 @@
|
||||||
|
from nose.tools import *
|
||||||
|
from airtime_analyzer.playability_analyzer import *
|
||||||
|
|
||||||
|
def check_default_metadata(metadata):
|
||||||
|
''' Stub function for now in case we need it later.'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_missing_liquidsoap():
|
||||||
|
old_ls = PlayabilityAnalyzer.LIQUIDSOAP_EXECUTABLE
|
||||||
|
PlayabilityAnalyzer.LIQUIDSOAP_EXECUTABLE = 'foosdaf'
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-stereo-utf8.mp3', dict())
|
||||||
|
PlayabilityAnalyzer.LIQUIDSOAP_EXECUTABLE = old_ls # Need to put this back
|
||||||
|
|
||||||
|
@raises(UnplayableFileError)
|
||||||
|
def test_invalid_filepath():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'non-existent-file', dict())
|
||||||
|
|
||||||
|
def test_mp3_utf8():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-stereo-utf8.mp3', dict())
|
||||||
|
check_default_metadata(metadata)
|
||||||
|
|
||||||
|
def test_mp3_dualmono():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-dualmono.mp3', dict())
|
||||||
|
check_default_metadata(metadata)
|
||||||
|
|
||||||
|
def test_mp3_jointstereo():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-jointstereo.mp3', dict())
|
||||||
|
check_default_metadata(metadata)
|
||||||
|
|
||||||
|
def test_mp3_simplestereo():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-simplestereo.mp3', dict())
|
||||||
|
check_default_metadata(metadata)
|
||||||
|
|
||||||
|
def test_mp3_stereo():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-stereo.mp3', dict())
|
||||||
|
check_default_metadata(metadata)
|
||||||
|
|
||||||
|
def test_mp3_mono():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-mono.mp3', dict())
|
||||||
|
check_default_metadata(metadata)
|
||||||
|
|
||||||
|
def test_ogg_stereo():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-stereo.ogg', dict())
|
||||||
|
check_default_metadata(metadata)
|
||||||
|
|
||||||
|
@raises(UnplayableFileError)
|
||||||
|
def test_invalid_wma():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-stereo-invalid.wma', dict())
|
||||||
|
|
||||||
|
def test_m4a_stereo():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-stereo.m4a', dict())
|
||||||
|
check_default_metadata(metadata)
|
||||||
|
|
||||||
|
def test_wav_stereo():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'tests/test_data/44100Hz-16bit-stereo.wav', dict())
|
||||||
|
check_default_metadata(metadata)
|
||||||
|
|
||||||
|
@raises(UnplayableFileError)
|
||||||
|
def test_unknown():
|
||||||
|
metadata = PlayabilityAnalyzer.analyze(u'http://www.google.com', dict())
|
||||||
|
check_default_metadata(metadata)
|
Loading…
Add table
Add a link
Reference in a new issue