app.py 3.1 KB

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