archiving community contributions on YouTube: unpublished captions, title and description translations and caption credits
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

78 lines
3.3 KiB

  1. import requests
  2. from json import loads
  3. def getmetadata(vid):
  4. params = (
  5. ("v", vid),
  6. )
  7. wpage = requests.get("https://www.youtube.com/watch", params=params)
  8. wptext = wpage.text
  9. initplay = None
  10. initdata = None
  11. recvids = set()
  12. recchans = set()
  13. recmixes = set()
  14. recplayl = set()
  15. for line in wptext.splitlines():
  16. if line.strip().startswith('window["ytInitialPlayerResponse"] = '):
  17. initplay = loads(line.split('window["ytInitialPlayerResponse"] = ', 1)[1].strip()[:-1])
  18. if initplay["playabilityStatus"]["status"] == "ERROR":
  19. print(vid, "unavailable")
  20. return False, recvids, recchans, recmixes, recplayl
  21. if "endscreen" in initplay.keys():
  22. for el in initplay["endscreen"]["endscreenRenderer"]:
  23. elint = el["endscreenElementRenderer"]
  24. if elint["style"] == "VIDEO":
  25. recvids.add(elint["endpoint"]["watchEndpoint"]["videoId"])
  26. elif elint["style"] == "CHANNEL":
  27. recchans.add(elint["endpoint"]["browseEndpoint"]["browseId"])
  28. elif elint["style"] == "PLAYLIST":
  29. recvids.add(elint["endpoint"]["watchEndpoint"]["videoId"])
  30. recplayl.add(elint["endpoint"]["watchEndpint"]["playlistId"])
  31. if "captions" in initplay.keys():
  32. ccenabled = "contribute" in initplay["captions"]["playerCaptionsRenderer"]
  33. recchans.add(initplay["videoDetails"]["channelId"])
  34. elif line.strip().startswith('window["ytInitialData"] = '):
  35. initdata = loads(line.split('window["ytInitialData"] = ', 1)[1].strip()[:-1])
  36. if "contents" in initdata.keys(): #prevent exception
  37. for recmd in initdata["contents"]["twoColumnWatchNextResults"]["secondaryResults"]["secondaryResults"]["results"]:
  38. #auto is like the others
  39. if "compactAutoplayRenderer" in recmd.keys():
  40. recmd = recmd["compactAutoplayRenderer"]["contents"][0]
  41. if "compactVideoRenderer" in recmd.keys():
  42. recvids.add(recmd["compactVideoRenderer"]["videoId"])
  43. recchans.add(recmd["compactVideoRenderer"]["channelId"])
  44. elif "compactPlaylistRenderer" in recmd.keys():
  45. recplayl.add(recmd["compactPlaylistRenderer"]["playlistId"])
  46. recvids.add(recmd["compactPlaylistRenderer"]["navigationEndpoint"]["watchEndpoint"]["videoId"])
  47. recchans.add(recmd["compactPlaylistRenderer"]["shortBylineText"]["navigationEndpoint"]["browseEndpoint"]["browseId"])
  48. elif "compactRadioRenderer" in recmd.keys(): #mix playlist
  49. recmixes.add(recmd["compactRadioRenderer"]["playlistId"])
  50. # todo: find out if channels can be suggested
  51. if initplay and initdata:
  52. break
  53. return ccenabled, recvids, recchans, recmixes, recplayl
  54. if __name__ == "__main__":
  55. from sys import argv
  56. vidl = argv
  57. vidl.pop(0)
  58. for video in vidl:
  59. print(getmetadata(video))