File: appletrailers.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 (142 lines) | stat: -rw-r--r-- 4,229 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
142
--[[
   Translate trailers.apple.com video webpages URLs to the corresponding
   movie URL

 Copyright © 2007-2010 the VideoLAN team

 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()
    return (vlc.access == "http" or vlc.access == "https")
        and string.match( vlc.path, "^trailers%.apple%.com/trailers/.+/.+" )
end

function find( haystack, needle )
    local _,_,r = string.find( haystack, needle )
    return r
end

function parse_json(url)
    vlc.msg.dbg("Trying to parse JSON from " .. url)
    local json = require ("dkjson")

    -- Use vlc.stream to grab a remote json file, place it in a string,
    -- decode it and return the decoded data.
    local stream = vlc.stream(url)
    local string = ""
    local line   = ""

    if not stream then return false end

    while true do
        line = stream:readline()
        if not line then break end

        string = string .. line
    end

    return json.decode(string)
end

-- Parse function.
function parse()
    local video_id = nil
    local playlist = {}

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

        if string.match(line, "FilmId%s+=%s+'%d+'") then
            video_id = find(line, "FilmId%s+=%s+'(%d+)'")
            vlc.msg.dbg("Found FilmId " .. video_id)
            break
        end
    end

    -- Found a video id
    if video_id ~= nil then
        -- Lookup info from the json endpoint
        local info = filmid_info(video_id)

        -- Parse data
        if info["clips"] == nil then
            vlc.msg.err("Unexpected JSON response from Apple trailers")
            return playlist
        end

        local movietitle = lookup_keys(info, "details/locale/en/movie_title")
        local desc       = lookup_keys(info, "details/locale/en/synopsis")

        for _, clip in ipairs(info["clips"]) do
            local item          = {}

            if clip["title"] == nil then
                item["name"] = movietitle
            else
                item["name"] = movietitle .. " (" .. clip["title"] .. ")"
            end
            item["path"]        = get_preferred_src(clip)
            item["artist"]      = clip["artist"]
            item["arturl"]      = clip["thumb"]
            item["description"] = desc
            item["url"]         = vlc.path

            table.insert(playlist, item)
        end
    else
        vlc.msg.err("Couldn't extract trailer video URL")
    end

    return playlist
end

-- Request, parse and return the info for a FilmID
function filmid_info(id)
    local film_url = "https://trailers.apple.com/trailers/feeds/data/" .. id .. ".json"
    vlc.msg.dbg("Fetching FilmID info from " .. film_url)

    return parse_json(film_url)
end

-- Get the user-preferred quality src
function get_preferred_src(clip)
    local resolution = vlc.var.inherit(nil, "preferred-resolution")
    if resolution == -1 then
        return lookup_keys(clip, "versions/enus/sizes/hd1080/srcAlt")
    end
    if resolution >= 1080 then
        return lookup_keys(clip, "versions/enus/sizes/hd1080/srcAlt")
    end
    if resolution >= 720 then
        return lookup_keys(clip, "versions/enus/sizes/hd720/srcAlt")
    end
    return lookup_keys(clip, "versions/enus/sizes/sd/srcAlt")
end

-- Resolve a "path" in a table or return nil if any of
-- the keys are not found
function lookup_keys(table, path)
    local value = table
    for token in path:gmatch( "[^/]+" ) do
        value = value[token]
        if value == nil then
            break
        end
    end
    return value
end