MythTV master
embedlrc.py
Go to the documentation of this file.
1from mutagen.flac import FLAC
2from mutagen.mp3 import MP3
3from mutagen.mp4 import MP4
4from mutagen.oggvorbis import OggVorbis
5from mutagen.apev2 import APEv2
6from lib.utils import *
7
8LANGUAGE = ADDON.getLocalizedString
9
10
12 def read(self, numBytes):
13 if numBytes == 0:
14 return b""
15 else:
16 return bytes(super().readBytes(numBytes))
17
18
19def getEmbedLyrics(song, getlrc, lyricssettings):
20 lyrics = Lyrics(settings=lyricssettings)
21 lyrics.song = song
22 lyrics.source = LANGUAGE(32002)
23 lyrics.lrc = getlrc
24 lry = lyrics.song.embed
25 if lry:
26 match = isLRC(lry)
27 if (getlrc and match) or ((not getlrc) and (not match)):
28 if lyrics.song.source:
29 lyrics.source = lyrics.song.source
30 lyrics.lyrics = lry
31 return lyrics
32 filename = song.filepath
33 ext = os.path.splitext(filename)[1].lower()
34 sup_ext = ['.mp3', '.flac', '.ogg', '.ape', '.m4a']
35 lry = None
36 if ext in sup_ext:
37 bfile = BinaryFile(filename)
38 if ext == '.mp3':
39 lry = getID3Lyrics(bfile, getlrc)
40 if not lry:
41 try:
42 lry = getLyrics3(bfile, getlrc)
43 except:
44 pass
45 elif ext == '.flac':
46 lry = getFlacLyrics(bfile, getlrc)
47 elif ext == '.m4a':
48 lry = getMP4Lyrics(bfile, getlrc)
49 elif ext == '.ogg':
50 lry = getOGGLyrics(bfile, getlrc)
51 elif ext == '.ape':
52 lry = getAPELyrics(bfile, getlrc)
53 bfile.close()
54 if not lry:
55 return None
56 lyrics.lyrics = lry
57 return lyrics
58
59'''
60Get lyrics embed with Lyrics3/Lyrics3V2 format
61See: http://id3.org/Lyrics3
62 http://id3.org/Lyrics3v2
63'''
64def getLyrics3(bfile, getlrc):
65 bfile.seek(-128-9, os.SEEK_END)
66 buf = bfile.read(9)
67 if (buf != b'LYRICS200' and buf != b'LYRICSEND'):
68 bfile.seek(-9, os.SEEK_END)
69 buf = bfile.read(9)
70 if (buf == b'LYRICSEND'):
71 ''' Find Lyrics3v1 '''
72 bfile.seek(-5100-9-11, os.SEEK_CUR)
73 buf = bfile.read(5100+11)
74 start = buf.find(b'LYRICSBEGIN')
75 data = buf[start+11:]
76 enc = chardet.detect(data)
77 content = data.decode(enc['encoding'])
78 if (getlrc and isLRC(content)) or (not getlrc and not isLRC(content)):
79 return content
80 elif (buf == b'LYRICS200'):
81 ''' Find Lyrics3v2 '''
82 bfile.seek(-9-6, os.SEEK_CUR)
83 size = int(bfile.read(6))
84 bfile.seek(-size-6, os.SEEK_CUR)
85 buf = bfile.read(11)
86 if(buf == b'LYRICSBEGIN'):
87 buf = bfile.read(size-11)
88 tags=[]
89 while buf!= '':
90 tag = buf[:3]
91 length = int(buf[3:8])
92 data = buf[8:8+length]
93 enc = chardet.detect(data)
94 content = data.decode(enc['encoding'])
95 if (tag == b'LYR'):
96 if (getlrc and isLRC(content)) or (not getlrc and not isLRC(content)):
97 return content
98 buf = buf[8+length:]
99
101 mins = '0%s' % int(ms/1000/60)
102 sec = '0%s' % int((ms/1000)%60)
103 msec = '0%s' % int((ms%1000)/10)
104 timestamp = '[%s:%s.%s]' % (mins[-2:],sec[-2:],msec[-2:])
105 return timestamp
106
107'''
108Get USLT/SYLT/TXXX lyrics embed with ID3v2 format
109See: http://id3.org/id3v2.3.0
110'''
111def getID3Lyrics(bfile, getlrc):
112 try:
113 data = MP3(bfile)
114 lyr = ''
115 for tag,value in data.items():
116 if getlrc and tag.startswith('SYLT'):
117 for line in data[tag].text:
118 txt = line[0].strip()
119 stamp = ms2timestamp(line[1])
120 lyr += '%s%s\r\n' % (stamp, txt)
121 elif not getlrc and tag.startswith('USLT'):
122 if data[tag].text:
123 lyr = data[tag].text
124 elif tag.startswith('TXXX'):
125 if getlrc and tag.upper().endswith('SYNCEDLYRICS'): # TXXX tags contain arbitrary info. only accept 'TXXX:SYNCEDLYRICS'
126 lyr = data[tag].text[0]
127 elif not getlrc and tag.upper().endswith('LYRICS'): # TXXX tags contain arbitrary info. only accept 'TXXX:LYRICS'
128 lyr = data[tag].text[0]
129 if lyr:
130 return lyr
131 except:
132 return
133
134def getFlacLyrics(bfile, getlrc):
135 try:
136 tags = FLAC(bfile)
137 if 'lyrics' in tags:
138 lyr = tags['lyrics'][0]
139 match = isLRC(lyr)
140 if (getlrc and match) or ((not getlrc) and (not match)):
141 return lyr
142 except:
143 return
144
145def getMP4Lyrics(bfile, getlrc):
146 try:
147 tags = MP4(bfile)
148 if '©lyr' in tags:
149 lyr = tags['©lyr'][0]
150 match = isLRC(lyr)
151 if (getlrc and match) or ((not getlrc) and (not match)):
152 return lyr
153 except:
154 return
155
156def getOGGLyrics(bfile, getlrc):
157 try:
158 tags = OggVorbis(bfile)
159 if 'lyrics' in tags:
160 lyr = tags['lyrics'][0]
161 match = isLRC(lyr)
162 if (getlrc and match) or ((not getlrc) and (not match)):
163 return lyr
164 except:
165 return
166
167def getAPELyrics(bfile, getlrc):
168 try:
169 tags = APEv2(bfile)
170 if 'lyrics' in tags:
171 lyr = tags['lyrics'][0]
172 match = isLRC(lyr)
173 if (getlrc and match) or ((not getlrc) and (not match)):
174 return lyr
175 except:
176 return
177
178def isLRC(lyr):
179 match = re.compile('\[(\d+):(\d\d)(\.\d+|)\]').search(lyr)
180 if match:
181 return True
182 else:
183 return False
def read(self, numBytes)
Definition: embedlrc.py:12
bytearray readBytes(self, int numBytes=0)
Definition: xbmcvfs.py:30
def getID3Lyrics(bfile, getlrc)
Definition: embedlrc.py:111
def ms2timestamp(ms)
Definition: embedlrc.py:100
def getFlacLyrics(bfile, getlrc)
Definition: embedlrc.py:134
LANGUAGE
Definition: embedlrc.py:8
def getMP4Lyrics(bfile, getlrc)
Definition: embedlrc.py:145
def getOGGLyrics(bfile, getlrc)
Definition: embedlrc.py:156
def getAPELyrics(bfile, getlrc)
Definition: embedlrc.py:167
def getLyrics3(bfile, getlrc)
Definition: embedlrc.py:64
def isLRC(lyr)
Definition: embedlrc.py:178
def getEmbedLyrics(song, getlrc, lyricssettings)
Definition: embedlrc.py:19