from flask import Flask, request, jsonify, render_template import yt_dlp app = Flask(__name__) def get_channel_icon_url(channel_id): # チャンネルIDがカスタムURL形式の場合、IDを変換する if channel_id.startswith('@'): # カスタムURL(@username)をYouTubeのチャンネルIDに変換 channel_id = get_channel_id_from_custom_url(channel_id) # yt-dlpオプション ydl_opts = { 'quiet': True, # 詳細なログを表示しない 'extract_flat': True, # メタデータのみを取得(ダウンロードはしない) } # yt-dlpを使ってチャンネル情報を取得 with yt_dlp.YoutubeDL(ydl_opts) as ydl: try: # チャンネルのメタデータを取得 info_dict = ydl.extract_info(f'https://www.youtube.com/channel/{channel_id}', download=False) # チャンネルのアイコンURLを取得 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(例:@username)からYouTubeのチャンネルID(UCxxxxxxx)を取得する url = f"https://www.youtube.com/{custom_url}" ydl_opts = { 'quiet': True, # 詳細なログを表示しない 'extract_flat': True, # メタデータのみを取得(ダウンロードはしない) } with yt_dlp.YoutubeDL(ydl_opts) as ydl: try: # カスタムURLを用いてチャンネル情報を取得 info_dict = ydl.extract_info(url, download=False) # 正しいチャンネルID(UCxxxxxxx)を取得 return info_dict['id'] # 'id'は通常、チャンネル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']: # 動画IDを取得 (URLから抽出) 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, # 新しいサムネイル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 # チャンネルアイコンURLを取得するAPIエンドポイント @app.route('/channel-icon', methods=['GET']) def channel_icon(): # URLパラメータからチャンネルIDを取得 channel_id = request.args.get('channel_id') if not channel_id: return jsonify({'error': 'channel_id is required'}), 400 # チャンネルアイコンのURLを取得 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') # 動画検索のAPIエンドポイント @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")