Advertisement
Guest User

Youtube Parser

a guest
Jun 7th, 2017
3,332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.94 KB | None | 0 0
  1. --[[
  2.  Youtube playlist importer for VLC media player 1.1 and 2.0
  3.  Copyright 2012 Guillaume Le Maout
  4.  
  5.  Authors:  Guillaume Le Maout
  6.  Contact: http://addons.videolan.org/messages/?action=newmessage&username=exebetche
  7.  
  8.  This program is free software; you can redistribute it and/or modify
  9.  it under the terms of the GNU General Public License as published by
  10.  the Free Software Foundation; either version 2 of the License, or
  11.  (at your option) any later version.
  12.  
  13.  This program is distributed in the hope that it will be useful,
  14.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  GNU General Public License for more details.
  17.  
  18.  You should have received a copy of the GNU General Public License
  19.  along with this program; if not, write to the Free Software
  20.  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  21. --]]
  22.  
  23. --[[
  24.  MODified by Kai Gillmann, 19.01.2013, kaigillmann@googlemail.com:
  25.  VLC HAS already a youtube importer, but not for playlists. IMO this mentioned one is
  26.  better than this one, because it opens the video in the best possible video resolution.
  27.  So i decided to remove all parts of the code which is not responsible for list handling.
  28.  Now this lua script parses the list, as wanted, but for each video opened, the vlc default
  29.  Youtube script is used, so the videos will be displayed properly.
  30. --]]
  31.  
  32.  --[[
  33.     Extension modified to handle bigger playlist mods done by Ginzo Milani, June 7th, 2017 Lf2owner@hotmail.com :
  34.     Kai had done a great job already, while there was improvements that could be done to better sort metadata, I was more
  35.     interested in just hearing the rest of my songs, thusly I've fixed his playlist plugin to allow bigger playlists from Youtube.
  36.     Interested in donating? Lf2owner@hotmail.com is my paypal, if it helped or suggestions feel free to email me those too!
  37.  --]]
  38. -- Helper function to get a parameter's value in a URL
  39. function get_url_param( url, name )
  40.      local _, _, res = string.find( url, "[&?]"..name.."=([^&]*)" )
  41.      return res
  42. end
  43.  
  44. -- Probe function.
  45. function probe()
  46.      if vlc.access ~= "http" and vlc.access ~= "https" then
  47.          return false
  48.      end
  49.          
  50.      return string.match(vlc.path:match("([^/]+)"),"%w+.youtube.com") and (string.match(vlc.path, "list="))
  51. end
  52.  
  53. -- Parse function.
  54. function parse()
  55.     if string.match( vlc.path, "list=" ) then
  56.         local playlist_parsed, playlistData, line, s, item
  57.         local p = {}
  58.         local id_ref = {}
  59.         local index = 1
  60.         local playlistID = get_url_param( vlc.path, "list" )
  61.         local videoID = get_url_param( vlc.path, "v" )
  62.         local playlistURL = "http://www.youtube.com/list_ajax?action_get_list=1&style=xml&list="..playlistID
  63.  
  64.         while true do
  65.             playlistData = ""
  66.             line = ""
  67.             s = nil
  68.             s = vlc.stream(playlistURL.."&index="..index)
  69.             while line do
  70.                 playlistData = playlistData..line
  71.                 line = s:readline()
  72.             end
  73.  
  74.             playlist_parsed = nil
  75.             playlist_parsed = parse_xml(playlistData).root.video
  76.            
  77.             for i, video in ipairs(playlist_parsed) do
  78.                 vlc.msg.err(i.." "..video.encrypted_id.CDATA)
  79.                 if id_ref[video.encrypted_id.CDATA]
  80.                 and id_ref[video.encrypted_id.CDATA] == i
  81.                 then
  82.                     return p
  83.                 else
  84.                     id_ref[video.encrypted_id.CDATA] = i
  85.                 end
  86.                
  87.                 item = nil
  88.                 item = {}
  89.                
  90.                 if video.encrypted_id
  91.                 and video.encrypted_id.CDATA then
  92.                     item.path = "http://www.youtube.com/watch?v="..video.encrypted_id.CDATA
  93.                 end
  94.                
  95.                 if video.title
  96.                 and video.title.CDATA then
  97.                     item.title = video.title.CDATA
  98.                 end
  99.                
  100.                 if video.artist
  101.                 and video.artist.CDATA then
  102.                     item.artist = video.artist.CDATA
  103.                 end
  104.                
  105.                 if video.thumbnail
  106.                 and video.thumbnail.CDATA then
  107.                     item.arturl = video.thumbnail.CDATA
  108.                 end
  109.                
  110.                 if video.description
  111.                 and video.description.CDATA then
  112.                     item.description = video.description.CDATA
  113.                 end
  114.                
  115.                 --~ item.rating = video.rating
  116.                 table.insert (p, item)
  117.             end
  118.             -- 1 to 200, 199 diff  (first 199 difference then 99 difference),
  119.             -- this should be a catch all for any future changes to the playlist count.
  120.             -- 200 to 299, 99 diff
  121.             -- 299 to 398, 99 diff
  122.             vlc.msg.info("[Youtube Playlist] Parsed: " .. tostring(#playlist_parsed) )
  123.             if #playlist_parsed > 99 then
  124.                 index = #playlist_parsed + index
  125.             elseif #playlist_parsed == 99 then
  126.                 index = index + 99
  127.             else
  128.                 return p
  129.             end
  130.         end
  131.     end
  132. end
  133.  
  134.  
  135. function parse_xml(data)
  136.     local tree = {}
  137.     local stack = {}
  138.     local tmp = {}
  139.     local tmpTag = ""
  140.     local level = 0
  141.  
  142.     table.insert(stack, tree)
  143.  
  144.     for op, tag, attr, empty, val in string.gmatch(
  145.         data,
  146.         "<(%p?)([^%s>/]+)([^>]-)(%/?)>[%s\r\n\t]*([^<]*)[%s\r\n\t]*") do
  147.         if op=="?" then
  148.             --~ DOCTYPE
  149.         elseif op=="/" then
  150.             if level>0 then
  151.             level = level - 1
  152.             table.remove(stack)
  153.             end
  154.         else
  155.         level = level + 1
  156.  
  157.         if op=="!" then
  158.             stack[level]['CDATA'] = vlc.strings.resolve_xml_special_chars(
  159.             string.gsub(tag..attr, "%[CDATA%[(.+)%]%]", "%1"))
  160.             attr = ""
  161.             level = level - 1
  162.         elseif type(stack[level][tag]) == "nil" then
  163.             stack[level][tag] = {}
  164.             table.insert(stack, stack[level][tag])
  165.         else
  166.             if type(stack[level][tag][1]) == "nil" then
  167.              tmp = nil
  168.              tmp = stack[level][tag]
  169.              stack[level][tag] = nil
  170.              stack[level][tag] = {}
  171.              table.insert(stack[level][tag], tmp)
  172.             end
  173.             tmp = nil
  174.             tmp = {}
  175.             table.insert(stack[level][tag], tmp)
  176.             table.insert(stack, tmp)
  177.             end
  178.  
  179.             if val~="" then
  180.             stack[level][tag]['CDATA'] = {}
  181.             stack[level][tag]['CDATA'] = vlc.strings.resolve_xml_special_chars(val)
  182.             end
  183.  
  184.             if attr ~= "" then
  185.             stack[level][tag]['ATTR'] = {}
  186.                 string.gsub(attr,
  187.                 "(%w+)=([\"'])(.-)%2",
  188.                 function (name, _, value)
  189.                  stack[level][tag]['ATTR'][name] = value
  190.                 end)
  191.             end
  192.  
  193.             if empty ~= "" then
  194.                 level = level - 1
  195.                 table.remove(stack)
  196.             end
  197.         end
  198.     end
  199.     return tree
  200. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement