app.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import logging
  2. import boto3
  3. import requests
  4. import yt_dlp
  5. from flask import Flask, request, Response, stream_with_context
  6. logging.basicConfig(format='%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d %(message)s',
  7. datefmt='%Y-%m-%d %H:%M:%S', level=logging.INFO)
  8. app = Flask(__name__)
  9. def get_key(url: str) -> str:
  10. return f"v2:{url}"
  11. def fetch_info(url):
  12. logging.info(f"fetching: {url}")
  13. with yt_dlp.YoutubeDL({
  14. "flat-playlist": True,
  15. "extract_flat": "flat-playlist"
  16. }) as ydl:
  17. info = ydl.extract_info(url, download=False)
  18. return info
  19. @app.route("/p", methods=["GET", "POST"])
  20. def p():
  21. video_id = request.args.get("videoId")
  22. format_id = request.args.get("formatId")
  23. if video_id and format_id:
  24. info = fetch_info(url=f"https://www.youtube.com/watch?v={video_id}")
  25. if info:
  26. for item in info.get("formats", []):
  27. if item.get("format_id") == format_id:
  28. url = item.get("url")
  29. response = requests.get(url, stream=True)
  30. logging.info(f"videoId: {video_id} status code: {response.status_code}")
  31. response_iter = response.iter_content(chunk_size=4096)
  32. response_iter = stream_with_context(response_iter)
  33. forwarded_response = Response(
  34. response_iter,
  35. status=response.status_code,
  36. headers=dict(response.headers.items()))
  37. return forwarded_response
  38. return {"status": 0}
  39. def convert_dto(info):
  40. thumbnails = []
  41. for item in info.get("thumbnails", []):
  42. if item.get("width"):
  43. thumbnails.append({
  44. "url": item.get("url", ""),
  45. "width": f"{item.get('width', 0)}",
  46. "height": f"{item.get('height', 0)}",
  47. })
  48. formats = []
  49. for item in info.get("formats", []):
  50. if item.get("resolution") != "audio only" and item.get("url") and item.get("acodec") and item.get(
  51. "acodec") != "none" and item.get("vcodec"):
  52. format_id = item.get("format_id")
  53. if format_id:
  54. url = f"http://d2sfgbpyanjzrq.cloudfront.net/p?videoId={info['display_id']}&formatId={format_id}",
  55. # url = f"http://e.justlistenmusic4560.com/p?videoId={info['display_id']}&formatId={format_id}"
  56. # url = item.get("url")
  57. formats.append({
  58. "width": f"{item.get('width', 0)}",
  59. "height": f"{item.get('height', 0)}",
  60. "type": item.get("format", ""),
  61. "quality": f'{item.get("format_note", "")}',
  62. "itag": 0,
  63. "fps": "0",
  64. "bitrate": "0",
  65. "url": url,
  66. "ext": item.get("ext"),
  67. "vcodec": item.get("vcodec", ""),
  68. "acodec": item.get("acodec", ""),
  69. "vbr": "0",
  70. "abr": "0",
  71. "container": item.get("container")
  72. })
  73. result = {
  74. "code": 200,
  75. "msg": "",
  76. "data": {
  77. "videoDetails": {
  78. "isLiveContent": info.get("is_live", False),
  79. "title": info.get("title", ""),
  80. "thumbnails": thumbnails,
  81. "description": info.get("description", ""),
  82. "lengthSeconds": f"{int(info.get('duration', 0) / 100)}",
  83. "viewCount": f"{info.get('view_count', 0)}",
  84. "keywords": [],
  85. "author": info.get("uploader", info.get("channel", "")),
  86. "channelID": info.get("channel_id", ""),
  87. "recommendInfo": [],
  88. "channelURL": info.get("channel_url", ""),
  89. "videoId": info.get("display_id", "")
  90. },
  91. "streamingData": {
  92. "formats": formats
  93. }
  94. },
  95. "id": "MusicDetailViewModel_detail_url"
  96. }
  97. return result
  98. @app.route("/extract", methods=["GET", "POST"])
  99. def extract():
  100. url: str = request.json.get("url")
  101. logging.info(f"url: {url}")
  102. info = fetch_info(url=url)
  103. return convert_dto(info=info)
  104. @app.route("/health", methods=["GET"])
  105. def health():
  106. return {
  107. "status": 1
  108. }
  109. @app.route("/refresh", methods=["GET"])
  110. def refresh():
  111. autoscaling = boto3.client(
  112. 'autoscaling',
  113. region_name="us-east-1",
  114. aws_access_key_id="AKIA2TBT2JUNG6X3W737",
  115. aws_secret_access_key="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")
  116. response = autoscaling.start_instance_refresh(
  117. AutoScalingGroupName="be-ytb-as")
  118. return {
  119. "response": response
  120. }
  121. if __name__ == '__main__':
  122. app.run(host='0.0.0.0', port=80, debug=True)