Merge branch 'cc-5709-airtime-analyzer' of github.com:sourcefabric/Airtime into cc-5709-airtime-analyzer
This commit is contained in:
commit
9cd200d42f
|
@ -1,6 +1,8 @@
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
import mutagen
|
import mutagen
|
||||||
|
import magic
|
||||||
|
import wave
|
||||||
import logging
|
import logging
|
||||||
from analyzer import Analyzer
|
from analyzer import Analyzer
|
||||||
|
|
||||||
|
@ -24,6 +26,12 @@ class MetadataAnalyzer(Analyzer):
|
||||||
#Other fields we'll want to set for Airtime:
|
#Other fields we'll want to set for Airtime:
|
||||||
metadata["hidden"] = False
|
metadata["hidden"] = False
|
||||||
|
|
||||||
|
# Mutagen doesn't handle WAVE files so we use a different package
|
||||||
|
mime_check = magic.from_file(filename, mime=True)
|
||||||
|
metadata["mime"] = mime_check
|
||||||
|
if mime_check == 'audio/x-wav':
|
||||||
|
return MetadataAnalyzer._analyze_wave(filename, metadata)
|
||||||
|
|
||||||
#Extract metadata from an audio file using mutagen
|
#Extract metadata from an audio file using mutagen
|
||||||
audio_file = mutagen.File(filename, easy=True)
|
audio_file = mutagen.File(filename, easy=True)
|
||||||
|
|
||||||
|
@ -37,17 +45,21 @@ class MetadataAnalyzer(Analyzer):
|
||||||
#Grab other file information that isn't encoded in a tag, but instead usually
|
#Grab other file information that isn't encoded in a tag, but instead usually
|
||||||
#in the file header. Mutagen breaks that out into a separate "info" object:
|
#in the file header. Mutagen breaks that out into a separate "info" object:
|
||||||
info = audio_file.info
|
info = audio_file.info
|
||||||
metadata["sample_rate"] = info.sample_rate
|
if hasattr(info, "sample_rate"): # Mutagen is annoying and inconsistent
|
||||||
metadata["length_seconds"] = info.length
|
metadata["sample_rate"] = info.sample_rate
|
||||||
#Converting the length in seconds (float) to a formatted time string
|
if hasattr(info, "length"):
|
||||||
track_length = datetime.timedelta(seconds=info.length)
|
metadata["length_seconds"] = info.length
|
||||||
metadata["length"] = str(track_length) #time.strftime("%H:%M:%S.%f", track_length)
|
#Converting the length in seconds (float) to a formatted time string
|
||||||
metadata["bit_rate"] = info.bitrate
|
track_length = datetime.timedelta(seconds=info.length)
|
||||||
|
metadata["length"] = str(track_length) #time.strftime("%H:%M:%S.%f", track_length)
|
||||||
# Other fields for Airtime
|
# Other fields for Airtime
|
||||||
metadata["cueout"] = metadata["length"]
|
metadata["cueout"] = metadata["length"]
|
||||||
|
|
||||||
#Use the mutagen to get the MIME type.
|
if hasattr(info, "bit_rate"):
|
||||||
|
metadata["bit_rate"] = info.bitrate
|
||||||
|
|
||||||
|
# Use the mutagen to get the MIME type, if it has one. This is more reliable and
|
||||||
|
# consistent for certain types of MP3s or MPEG files than the MIMEs returned by magic.
|
||||||
if audio_file.mime:
|
if audio_file.mime:
|
||||||
metadata["mime"] = audio_file.mime[0]
|
metadata["mime"] = audio_file.mime[0]
|
||||||
|
|
||||||
|
@ -122,33 +134,20 @@ class MetadataAnalyzer(Analyzer):
|
||||||
|
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _analyze_wave(filename, metadata):
|
||||||
'''
|
try:
|
||||||
For reference, the Airtime metadata fields are:
|
reader = wave.open(filename, 'rb')
|
||||||
title
|
metadata["mime"] = magic.from_file(filename, mime=True)
|
||||||
artist ("Creator" in Airtime)
|
metadata["channels"] = reader.getnchannels()
|
||||||
album
|
metadata["sample_rate"] = reader.getframerate()
|
||||||
bit rate
|
length_seconds = float(reader.getnframes()) / float(metadata["channels"] * metadata["sample_rate"])
|
||||||
BPM
|
#Converting the length in seconds (float) to a formatted time string
|
||||||
composer
|
track_length = datetime.timedelta(seconds=length_seconds)
|
||||||
conductor
|
metadata["length"] = str(track_length) #time.strftime("%H:%M:%S.%f", track_length)
|
||||||
copyright
|
metadata["length_seconds"] = length_seconds
|
||||||
cue in
|
metadata["cueout"] = metadata["length"]
|
||||||
cue out
|
except wave.Error:
|
||||||
encoded by
|
logging.error("Invalid WAVE file.")
|
||||||
genre
|
raise
|
||||||
ISRC
|
return metadata
|
||||||
label
|
|
||||||
language
|
|
||||||
last modified
|
|
||||||
length
|
|
||||||
mime
|
|
||||||
mood
|
|
||||||
owner
|
|
||||||
replay gain
|
|
||||||
sample rate
|
|
||||||
track number
|
|
||||||
website
|
|
||||||
year
|
|
||||||
'''
|
|
||||||
|
|
|
@ -6,8 +6,17 @@ stop on runlevel [!2345]
|
||||||
|
|
||||||
respawn
|
respawn
|
||||||
|
|
||||||
|
setuid www-data
|
||||||
|
setgid www-data
|
||||||
|
|
||||||
|
expect fork
|
||||||
|
|
||||||
env LANG='en_US.UTF-8'
|
env LANG='en_US.UTF-8'
|
||||||
env LC_ALL='en_US.UTF-8'
|
env LC_ALL='en_US.UTF-8'
|
||||||
|
|
||||||
exec su www-data -c "airtime_analyzer"
|
script
|
||||||
|
airtime_analyzer
|
||||||
|
end script
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ setup(name='airtime_analyzer',
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'mutagen',
|
'mutagen',
|
||||||
'pika',
|
'pika',
|
||||||
|
'python-magic',
|
||||||
'nose',
|
'nose',
|
||||||
'coverage',
|
'coverage',
|
||||||
'mock',
|
'mock',
|
||||||
|
|
Loading…
Reference in New Issue