2 -- Copyright (C) 2012 Toni Gundogdu <legatvs@gmail.com>
3 -- Copyright (C) 2011 Raphaƫl Droz <raphael.droz+floss@gmail.com>
5 -- This file is part of libquvi-scripts <http://quvi.googlecode.com/>.
7 -- This library is free software; you can redistribute it and/or
8 -- modify it under the terms of the GNU Lesser General Public
9 -- License as published by the Free Software Foundation; either
10 -- version 2.1 of the License, or (at your option) any later version.
12 -- This library 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 GNU
15 -- Lesser General Public License for more details.
17 -- You should have received a copy of the GNU Lesser General Public
18 -- License along with this library; if not, write to the Free Software
19 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 -- NOTE: Most videos expire some (7?) days after their original broadcast
24 local Arte
= {} -- Utility functions unique to to this script.
26 -- Identify the media script.
29 can_parse_url
= Arte
.can_parse_url(qargs
),
30 domains
= table.concat({'videos.arte.tv'}, ',')
34 -- Parse media properties.
36 local L
= require
'quvi/lxph'
37 local P
= require
'lxp.lom'
39 -- Config data ('c') contains config data for each available language.
40 -- Each language consists of >0 media streams, e.g. 'hd', 'sd'.
42 local c
,lang_code
= Arte
.get_config(qargs
, L
, P
)
43 qargs
.streams
,S
= Arte
.iter_streams(c
, L
, P
, lang_code
)
45 -- Many of the optional properties depend on the language setting.
46 -- e.g. title, even the media ID. Have these parsed _after_ the
47 -- streams have been parsed.
49 Arte
.opt_properties(qargs
, lang_code
);
58 function Arte
.can_parse_url(qargs
)
59 local U
= require
'socket.url'
60 local t
= U
.parse(qargs
.input_url
)
61 if t
and t
.scheme
and t
.scheme
:lower():match('^http$')
62 and t
.host
and t
.host
:lower():match('^videos%.arte%.tv$')
63 and t
.path
and t
.path
:lower():match('^/%w+/videos/')
71 function Arte
.get_config(qargs
, L
, P
)
73 -- Collect all config data for all available (language) streams.
74 -- Return a list containing the config dictionaries, and the language
75 -- code which will be used to select the default and the best streams.
77 local p
= quvi
.fetch(qargs
.input_url
)
79 local u
= p
:match('videorefFileUrl = "(.-)"')
80 or error('no match: config URL')
82 local l
= u
:match('%.tv/(%w+)/') or error('no match: lang code')
84 local C
= require
'quvi/const'
85 local o
= { [C
.qfo_type
] = C
.qft_config
}
86 local c
= quvi
.fetch(u
, o
)
88 local x
= lxp
.lom
.parse(c
)
89 local v
= L
.find_first_tag(x
, 'videos')
92 for i
=1, #v
do -- For each language in the config.
93 if v
[i
].tag == 'video' then
94 local d
= quvi
.fetch(v
[i
].attr
['ref'], o
)
96 lang_code
= v
[i
].attr
['lang'],
99 -- Make the stream the first in the list if the language codes
100 -- match, making it the new default stream.
101 table.insert(r
, ((t
.lang_code
== l
) and 1 or #t
), t
)
108 function Arte
.opt_properties(qargs
, lang_code
)
110 -- The first stream should now be the default stream. This should
111 -- apply to the 'best' stream also, they are both the first streams
112 -- in the stream list.
114 local r
= qargs
.streams
[1]
115 qargs
.thumb_url
= r
.nostd
.thumb_url
116 qargs
.title
= r
.nostd
.title
117 qargs
.id
= r
.nostd
.id
120 function Arte
.iter_streams(config
, L
, P
, lang_code
)
121 local S
= require
'quvi/stream'
122 local U
= require
'quvi/util'
125 for _
,v
in pairs(config
) do -- For each language in the config.
126 local c
= P
.parse(v
.lang_data
)
128 local d
= L
.find_first_tag(c
, 'dateExpiration')[1]
129 if Arte
.has_expired(d
, U
) then
130 error('media no longer available (expired)')
133 local urls
= L
.find_first_tag(c
, 'urls')
136 if urls
[i
].tag == 'url' then
137 local t
= S
.stream_new(urls
[i
][1])
139 -- Save the property values that may be used later, these depend
140 -- on the language setting. Many of these are the so called
141 -- "optional media properties". The 'nostd' dictionary is used
142 -- only by this script. libquvi ignores it completely.
145 thumb_url
= L
.find_first_tag(c
, 'firstThumbnailUrl')[1],
146 title
= L
.find_first_tag(c
, 'name')[1],
147 quality
= urls
[i
].attr
['quality'],
148 lang_code
= c
.attr
['lang'],
149 id
= c
.attr
['id'] or ''
158 Arte
.ch_best(S
, r
, lang_code
)
164 function Arte
.has_expired(s
, U
)
165 return (U
.to_timestamp(s
) - os
.time()) <0
168 function Arte
.ch_best(S
, t
, lang_code
)
169 local r
= t
[1] -- Make the first one the 'best' by default.
171 for _
,v
in pairs(t
) do -- Whatever matches 'hd' first.
172 if v
.id
:match('hd') and v
.nostd
.lang_code
== lang_code
then
173 r
= S
.swap_best(r
, v
)
178 -- Return an ID for a stream.
179 function Arte
.to_id(t
)
180 return string.format("%s_%s", t
.nostd
.quality
, t
.nostd
.lang_code
)
183 -- vim: set ts=2 sw=2 tw=72 expandtab: