]> git.sesse.net Git - vlc/blob - share/lua/playlist/cue.lua
794a400077eca76b06b954352144388054ced060
[vlc] / share / lua / playlist / cue.lua
1 --[[
2    Parse CUE files
3
4  $Id$
5  Copyright (C) 2009 Laurent Aimar
6
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  GNU General Public License for more details.
16
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20 --]]
21
22 -- Probe function.
23 function probe()
24         if( not string.match( string.upper( vlc.path ), ".CUE$" ) ) then
25                 return false
26         end
27         header = vlc.peek( 2048 )
28         return string.match( header, "FILE.*WAVE%s*[\r\n]+" ) or
29                string.match( header, "FILE.*AIFF%s*[\r\n]+" ) or
30                string.match( header, "FILE.*MP3%s*[\r\n]+" )
31 end
32
33 -- Helpers
34 function cue_string( src )
35         local sub = string.match( src, "^\"(.*)\".*$" );
36         if( sub ) then
37                 return sub
38         end
39         return string.match( src, "^(%S+).*$" )
40 end
41
42 function cue_path( src )
43         if( string.match( src, "^/" ) or
44                 string.match( src, "^\\" ) or
45                 string.match( src, "^[%l%u]:\\" ) ) then
46                 return vlc.strings.make_uri(src)
47         end
48
49         local slash = string.find( string.reverse( vlc.path ), '/' )
50         local prefix = vlc.access .. "://" .. string.sub( vlc.path, 1, -slash )
51         -- FIXME: postfix may not be encoded correctly (esp. slashes)
52         local postfix = vlc.strings.encode_uri_component(src)
53         return prefix .. postfix
54 end
55
56 function cue_track( global, track )
57         if( track.index01 == nil ) then
58                 return nil
59         end
60
61         t = {}
62         t.path = cue_path( track.file or global.file )
63         t.title = track.title
64         t.album = global.title
65         t.artist = track.performer or global.performer
66         t.genre = track.genre or global.genre
67         t.date = track.date or global.date
68         t.description = global.comment
69         t.tracknum = track.num
70         t.options = { ":start-time=" .. math.floor(track.index01) }
71
72         return t
73 end
74
75 function cue_append( tracks, global, track )
76         local t = cue_track( global, track )
77         if( t ~= nil ) then
78                 if( #tracks > 0 ) then
79                         local prev = tracks[#tracks]
80                         table.insert( prev.options, ":stop-time=" .. math.floor(track.index01) )
81                 end
82                 table.insert( tracks, t )
83         end
84 end
85
86 -- Parse function.
87 function parse()
88     p = {}
89         global_data = nil
90         data = {}
91         file = nil
92
93     while true
94     do 
95         line = vlc.readline()
96         if not line then break end
97
98                 cmd, arg = string.match( line, "^%s*(%S+)%s*(.*)$" )
99
100                 if(  cmd == "REM" and arg ) then
101                         subcmd, value = string.match( arg, "^(%S+)%s*(.*)$" )
102                         if( subcmd == "GENRE" and value ) then
103                                 data.genre = cue_string( value )
104                         elseif( subcmd == "DATE" and value ) then
105                                 data.date = cue_string( value )
106                         elseif( subcmd == "COMMENT" and value ) then
107                                 data.comment = cue_string( value )
108                         end
109                 elseif( cmd == "PERFORMER" and arg ) then
110                         data.performer = cue_string( arg )
111                 elseif( cmd == "TITLE" and arg ) then
112                         data.title = cue_string( arg )
113                 elseif( cmd == "FILE" ) then
114                         file = cue_string( arg )
115                 elseif( cmd == "TRACK" ) then
116                         if( not global_data ) then
117                                 global_data = data
118                         else
119                                 cue_append( p, global_data, data )
120                         end
121                         data =  { file = file, num = string.match( arg, "^(%d+)" ) }
122                 elseif( cmd == "INDEX" ) then
123                         local idx, m, s, f = string.match( arg, "(%d+)%s+(%d+):(%d+):(%d+)" )
124                         if( idx == "01" and m ~= nil and s ~= nil and f ~= nil ) then
125                                 data.index01 = m * 60 + s + f / 75
126                         end
127                 end
128     end
129
130         cue_append( p, global_data, data )
131
132     return p
133 end
134