|
from flask import Flask, request, jsonify, render_template |
|
import yt_dlp |
|
|
|
app = Flask(__name__) |
|
|
|
|
|
|
|
def get_channel_icon_url(channel_id): |
|
|
|
if channel_id.startswith('@'): |
|
|
|
channel_id = get_channel_id_from_custom_url(channel_id) |
|
|
|
|
|
ydl_opts = { |
|
'quiet': True, |
|
'extract_flat': True, |
|
} |
|
|
|
|
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl: |
|
try: |
|
|
|
info_dict = ydl.extract_info(f'https://www.youtube.com/channel/{channel_id}', download=False) |
|
|
|
icon_url = info_dict.get('avatar', None) |
|
return icon_url |
|
except Exception as e: |
|
print(f"Error: {e}") |
|
return None |
|
|
|
def get_channel_id_from_custom_url(custom_url): |
|
|
|
url = f"https://www.youtube.com/{custom_url}" |
|
|
|
ydl_opts = { |
|
'quiet': True, |
|
'extract_flat': True, |
|
} |
|
|
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl: |
|
try: |
|
|
|
info_dict = ydl.extract_info(url, download=False) |
|
|
|
return info_dict['id'] |
|
except Exception as e: |
|
print(f"Error fetching channel ID from custom URL: {e}") |
|
return None |
|
|
|
|
|
|
|
def search_videos(query): |
|
ydl_opts = { |
|
'quiet': True, |
|
'extract_flat': True, |
|
'format': 'best', |
|
} |
|
|
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl: |
|
result = ydl.extract_info(f"ytsearch5:{query}", download=False) |
|
|
|
videos = [] |
|
if 'entries' in result: |
|
for entry in result['entries']: |
|
|
|
video_id = entry.get('id', '') |
|
thumbnail_url = f"https://inv.nadeko.net/vi/{video_id}/mqdefault.jpg" if video_id else '' |
|
|
|
video = { |
|
'title': entry.get('title', 'No Title'), |
|
'url': entry.get('url', ''), |
|
'thumbnail': thumbnail_url, |
|
'duration': entry.get('duration', 0), |
|
'view_count': entry.get('view_count', 0), |
|
'uploader': entry.get('uploader', 'Unknown'), |
|
'uploader_url': entry.get('uploader_url', ''), |
|
'uploader_thumbnail': entry.get('channel_favicon', '') |
|
} |
|
|
|
videos.append(video) |
|
|
|
return videos |
|
|
|
|
|
@app.route('/channel-icon', methods=['GET']) |
|
def channel_icon(): |
|
|
|
channel_id = request.args.get('channel_id') |
|
|
|
if not channel_id: |
|
return jsonify({'error': 'channel_id is required'}), 400 |
|
|
|
|
|
icon_url = get_channel_icon_url(channel_id) |
|
|
|
if icon_url: |
|
return jsonify({'icon_url': icon_url}) |
|
else: |
|
return jsonify({'error': 'Could not fetch channel icon'}), 404 |
|
|
|
|
|
@app.route('/') |
|
def index(): |
|
return render_template('index.html') |
|
|
|
|
|
@app.route('/search', methods=['GET']) |
|
def search(): |
|
query = request.args.get('query', '') |
|
if not query: |
|
return jsonify({'error': 'No query provided'}), 400 |
|
|
|
try: |
|
videos = search_videos(query) |
|
return jsonify(videos) |
|
except Exception as e: |
|
return jsonify({'error': str(e)}), 500 |
|
|
|
|
|
if __name__ == '__main__': |
|
app.run(debug=True, port=7860, host="0.0.0.0") |