Recognizes if input is ogg or not.
[xiph/unicode.git] / positron / positron / audiofile.py
blob2223021e87e2e414a9b14438d97cbdbb72ef6d25
1 # -*- Mode: python -*-
3 # audiofile.py - audio file handling
5 # Copyright (C) 2003, Xiph.org Foundation
7 # This file is part of positron.
9 # This program is free software; you can redistribute it and/or modify it
10 # under the terms of a BSD-style license (see the COPYING file in the
11 # distribution).
13 # This program is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
15 # or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17 from types import *
18 import os
19 from os import path
20 import string
21 import struct
23 import MP3Info
25 def detect(filename):
26 metadata = None
28 for detect_func in detect_functions:
29 metadata = detect_func(filename)
30 if metadata != None:
31 break
32 else:
33 metadata = None
35 if metadata != None and metadata["title"] == None:
36 # Must have title
37 metadata["title"] = path.split(filename)[1]
39 return metadata
41 def detect_mp3(filename):
42 try:
43 f = file(filename, "rb")
45 mp3info = MP3Info.MP3Info(f)
47 header = mp3info.mpeg
48 info = { "type" : "mp3",
49 "size" : header.filesize,
50 "length" : header.length,
51 "title" : mp3info.title,
52 "artist" : mp3info.artist,
53 "album" : mp3info.album,
54 "genre" : mp3info.genre,
55 "tracknumber" : mp3info.track}
57 # Convert empty string entries to nulls
58 for key in info.keys():
59 if info[key] == "":
60 info[key] = None
62 f.close()
64 except MP3Info.Error:
65 f.close()
66 return None
67 except IOError:
68 return None
69 except OSError:
70 return None
72 return info
74 def detect_oggvorbis(filename):
75 try:
76 vf = ogg.vorbis.VorbisFile(filename)
77 vc = vf.comment()
78 vi = vf.info()
80 info = { "type" : "oggvorbis",
81 "size" : os.stat(filename).st_size,
82 "length" : int(vf.time_total(-1)),
83 "title" : None,
84 "artist" : None,
85 "album" : None,
86 "genre" : None,
87 "tracknumber" : None}
89 actual_keys = []
90 for tag in vc.keys():
91 try:
92 actual_keys.append(tag.lower())
93 except UnicodeError:
94 pass # Don't let bad tags stop us
96 for tag in ("title","artist","album","genre","tracknumber"):
97 if tag in actual_keys:
98 try:
99 value = vc[tag]
100 # Force these to be single valued
101 if type(value) == ListType or type(value) == TupleType:
102 value = value[0]
104 # Convert from Unicode to ASCII since the Neuros can't
105 # do Unicode anyway.
107 # I will probably burn in i18n hell for this.
108 info[tag] = value.encode('ascii','replace')
109 except UnicodeError:
110 pass
112 except ogg.vorbis.VorbisError:
113 return None
114 except IOError:
115 return None
116 except OSError:
117 return None
119 return info
121 def detect_wav(filename):
122 if filename[-4:] in ['.wav','.WAV','.Wav']:
123 info = { "type" : "wav",
124 "size" : os.stat(filename).st_size,
125 "length" : 1,
126 "title" : None,
127 "artist" : None,
128 "album" : None,
129 "genre" : None,
130 "tracknumber" : None}
131 wav_file=open(filename)
132 wav_file.seek(0x04,0)
133 size = int(struct.unpack('1i',wav_file.read(4))[0])
134 wav_file.seek(0x1c,0)
135 bytes_sec = int(struct.unpack('1i',wav_file.read(4))[0])
136 wav_file.close()
137 duration = size/bytes_sec
139 info["length"] = duration
140 return info
141 else:
142 return None
144 # Only put the ogg vorbis detection code in the list if
145 # we have the python module needed.
147 detect_functions = [detect_mp3,detect_wav]
149 try:
150 import ogg.vorbis
151 detect_functions.insert(0, detect_oggvorbis)
152 except ImportError:
153 pass