File: cue.lua

package info (click to toggle)
vlc 3.0.23-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 208,024 kB
  • sloc: ansic: 443,448; cpp: 111,223; objc: 36,399; sh: 6,737; makefile: 6,627; javascript: 4,902; xml: 1,611; asm: 1,355; yacc: 644; python: 321; lex: 88; perl: 77; sed: 16
file content (141 lines) | stat: -rw-r--r-- 4,381 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
--[[
   Parse CUE files

 Copyright (C) 2009 Laurent Aimar

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
--]]

-- Probe function.
function probe()
    if( not string.match( vlc.path, "%.[cC][uU][eE]$" ) ) then
        return false
    end
    header = vlc.peek( 2048 )
    return string.match( header, "FILE.*WAVE%s*[\r\n]+" ) or
           string.match( header, "FILE.*AIFF%s*[\r\n]+" ) or
           string.match( header, "FILE.*MP3%s*[\r\n]+" )
end

-- Helpers
function is_utf8( src )
    return vlc.strings.from_charset( "UTF-8", src ) == src
end

function cue_string( src )
    if not is_utf8( src ) then
        -- Convert to UTF-8 since it's probably Latin1
        src = vlc.strings.from_charset( "ISO_8859-1", src )
    end
    local sub = string.match( src, "^\"(.*)\".*$" );
    if( sub ) then
        return sub
    end
    return string.match( src, "^(%S+).*$" )
end

function cue_path( src )
    if( string.match( src, "^/" ) or
        string.match( src, "^\\" ) or
        string.match( src, "^[%l%u]:\\" ) ) then
        return vlc.strings.make_uri(src)
    end

    local slash = string.find( string.reverse( vlc.path ), '/' )
        local prefix = vlc.access .. "://" .. string.sub( vlc.path, 1, -slash )
        -- FIXME: postfix may not be encoded correctly (esp. slashes)
        local postfix = vlc.strings.encode_uri_component(src)
    return prefix .. postfix
end

function cue_track( global, track )
    if( track.index01 == nil ) then
        return nil
    end

    t = {}
    t.path = cue_path( track.file or global.file )
    t.title = track.title
    t.album = global.title
    t.artist = track.performer or global.performer
    t.genre = track.genre or global.genre
    t.date = track.date or global.date
    t.description = global.comment
    t.tracknum = track.num
    t.options = { ":start-time=" .. track.index01}

    return t
end

function cue_append( tracks, global, track )
    local t = cue_track( global, track )
    if( t ~= nil ) then
        if( #tracks > 0 ) then
            local prev = tracks[#tracks]
            table.insert( prev.options, ":stop-time=" .. track.index01)
        end
        table.insert( tracks, t )
    end
end

-- Parse function.
function parse()
    p = {}
    global_data = nil
    data = {}
    file = nil

    while true
    do 
        line = vlc.readline()
        if not line then break end

        cmd, arg = string.match( line, "^%s*(%S+)%s*(.*)$" )

        if(  cmd == "REM" and arg ) then
            subcmd, value = string.match( arg, "^(%S+)%s*(.*)$" )
            if( subcmd == "GENRE" and value ) then
                data.genre = cue_string( value )
            elseif( subcmd == "DATE" and value ) then
                data.date = cue_string( value )
            elseif( subcmd == "COMMENT" and value ) then
                data.comment = cue_string( value )
            end
        elseif( cmd == "PERFORMER" and arg ) then
            data.performer = cue_string( arg )
        elseif( cmd == "TITLE" and arg ) then
            data.title = cue_string( arg )
        elseif( cmd == "FILE" ) then
            file = cue_string( arg )
        elseif( cmd == "TRACK" ) then
            if( not global_data ) then
                global_data = data
            else
                cue_append( p, global_data, data )
            end
            data =  { file = file, num = string.match( arg, "^(%d+)" ) }
        elseif( cmd == "INDEX" ) then
            local idx, m, s, f = string.match( arg, "(%d+)%s+(%d+):(%d+):(%d+)" )
            if( idx == "01" and m ~= nil and s ~= nil and f ~= nil ) then
                data.index01 = m * 60 + s + f / 75
            end
        end
    end

    cue_append( p, global_data, data )

    return p
end