app.py 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import logging
  2. import yt_dlp
  3. from flask import Flask, request
  4. from tinydb import TinyDB
  5. logging.basicConfig(format='%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d %(message)s',
  6. datefmt='%Y-%m-%d %H:%M:%S', level=logging.INFO)
  7. app = Flask(__name__)
  8. db = TinyDB('data.json')
  9. def get_key(url: str) -> str:
  10. return f"v1:{url}"
  11. @app.route("/extract", methods=["GET", "POST"])
  12. def extract():
  13. url = request.json.get("url")
  14. logging.info(f"url: ${url}")
  15. key = get_key(url=url)
  16. result = db.search(lambda x: x.get("key") == key)
  17. if result:
  18. logging.info("find from data.json, so return")
  19. if result[0].get("result"):
  20. return result[0].get("result")
  21. with yt_dlp.YoutubeDL({"flat-playlist": True, "extract_flat": "flat-playlist"}) as ydl:
  22. info = ydl.extract_info(url, download=False)
  23. thumbnails = []
  24. for item in info.get("thumbnails", []):
  25. if item.get("width"):
  26. thumbnails.append({
  27. "url": item.get("url", ""),
  28. "width": item.get("width", 0),
  29. "height": item.get("height", 0),
  30. })
  31. formats = []
  32. for item in info.get("formats", []):
  33. if item.get("resolution") != "audio only" and item.get("url") and item.get("acodec") and item.get(
  34. "acodec") != "none" and item.get("vcodec"):
  35. formats.append({
  36. "width": item.get("width", 0),
  37. "height": item.get("height", 0),
  38. "type": item.get("format", ""),
  39. "quality": f'{item.get("format_note", "")}',
  40. "itag": 0,
  41. "fps": 0,
  42. "bitrate": 0,
  43. "url": item.get("url", ""),
  44. "ext": item.get("ext"),
  45. "vcodec": item.get("vcodec", ""),
  46. "acodec": item.get("acodec", ""),
  47. "vbr": 0,
  48. "abr": 0,
  49. "container": item.get("container")
  50. })
  51. result = {
  52. "code": 200,
  53. "msg": "",
  54. "data": {
  55. "videoDetails": {
  56. "isLiveContent": info.get("is_live", False),
  57. "title": info.get("title", ""),
  58. "thumbnails": thumbnails,
  59. "description": info.get("description", ""),
  60. "lengthSeconds": int(info.get("duration", 0) / 100),
  61. "viewCount": f"{info.get('view_count', 0)}",
  62. "keywords": [],
  63. "author": info.get("uploader", info.get("channel", "")),
  64. "channelID": info.get("channel_id", ""),
  65. "recommendInfo": [],
  66. "channelURL": info.get("channel_url", ""),
  67. "videoId": info.get("display_id", "")
  68. },
  69. "streamingData": {
  70. "formats": formats
  71. }
  72. },
  73. "id": "MusicDetailViewModel_detail_url"
  74. }
  75. db.insert({"result": result, "key": key})
  76. return result
  77. if __name__ == '__main__':
  78. app.run(host='0.0.0.0', port=80, debug=True)