]> git.sesse.net Git - vlc/blob - share/lua/playlist/cue.lua
CUE: support Unix Line Endings
[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]+" ) or
31                string.match( header, "FILE.*WAVE%s*[\n]+" ) or
32                string.match( header, "FILE.*AIFF%s*[\n]+" ) or
33                string.match( header, "FILE.*MP3%s*[\n]+" )
34 end
35
36 -- Helpers
37 function cue_string( src )
38         local sub = string.match( src, "^\"(.*)\".*$" );
39         if( sub ) then
40                 return sub
41         end
42         return string.match( src, "^(%S+).*$" )
43 end
44
45 function cue_path( src )
46         if( string.match( src, "^/" ) or
47                 string.match( src, "^\\" ) or
48                 string.match( src, "^[%l%u]:\\" ) ) then
49                 return src
50         end
51
52         local path = string.gsub( vlc.path, '\\', '/' )
53         local slash = string.find( string.reverse( path ), '/' )
54         if( path == nil ) then
55                 return src
56         end
57         return string.sub( path, 1, -slash-1 ) .. '/' .. src
58 end
59
60 function cue_track( global, track )
61         if( track.index01 == nil ) then
62                 return nil
63         end
64
65         t = {}
66         t.path = vlc.strings.make_uri(cue_path( track.file or global.file ))
67         t.title = track.title
68         t.album = global.title
69         t.artist = track.performer or global.performer
70         t.genre = track.genre or global.genre
71         t.date = track.date or global.date
72         t.description = global.comment
73         t.tracknum = track.num
74         t.options = { ":start-time=" .. math.floor(track.index01) }
75
76         return t
77 end
78
79 function cue_append( tracks, global, track )
80         local t = cue_track( global, track )
81         if( t ~= nil ) then
82                 if( #tracks > 0 ) then
83                         local prev = tracks[#tracks]
84                         table.insert( prev.options, ":stop-time=" .. math.floor(track.index01) )
85                 end
86                 table.insert( tracks, t )
87         end
88 end
89
90 -- Parse function.
91 function parse()
92     p = {}
93         global_data = nil
94         data = {}
95         file = nil
96
97     while true
98     do 
99         line = vlc.readline()
100         if not line then break end
101
102                 cmd, arg = string.match( line, "^%s*(%S+)%s*(.*)$" )
103
104                 if(  cmd == "REM" and arg ) then
105                         subcmd, value = string.match( arg, "^(%S+)%s*(.*)$" )
106                         if( subcmd == "GENRE" and value ) then
107                                 data.genre = cue_string( value )
108                         elseif( subcmd == "DATE" and value ) then
109                                 data.date = cue_string( value )
110                         elseif( subcmd == "COMMENT" and value ) then
111                                 data.comment = cue_string( value )
112                         end
113                 elseif( cmd == "PERFORMER" and arg ) then
114                         data.performer = cue_string( arg )
115                 elseif( cmd == "TITLE" and arg ) then
116                         data.title = cue_string( arg )
117                 elseif( cmd == "FILE" ) then
118                         file = cue_string( arg )
119                 elseif( cmd == "TRACK" ) then
120                         if( not global_data ) then
121                                 global_data = data
122                         else
123                                 cue_append( p, global_data, data )
124                         end
125                         data =  { file = file, num = string.match( arg, "^(%d+)" ) }
126                 elseif( cmd == "INDEX" ) then
127                         local idx, m, s, f = string.match( arg, "(%d+)%s+(%d+):(%d+):(%d+)" )
128                         if( idx == "01" and m ~= nil and s ~= nil and f ~= nil ) then
129                                 data.index01 = m * 60 + s + f / 75
130                         end
131                 end
132     end
133
134         cue_append( p, global_data, data )
135
136     return p
137 end
138