#!/usr/bin/python3
# -*- coding: utf-8 -*-
import json
import re
import gradio as gr
from jinja2 import Template
import tempfile
html_content = """
YouTube视频连续播放器
YouTube视频连续播放器
准备播放...
"""
def make_file(content: str):
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.html') as tmp:
tmp.write(content)
tmp_path = tmp.name
return tmp_path
def get_video_id(url: str):
"""
从各种YouTube URL格式中提取视频ID
支持的格式包括:
- 普通URL: https://www.youtube.com/watch?v=dQw4w9WgXcQ
- 短链接: https://youtu.be/dQw4w9WgXcQ
- 嵌入链接: https://www.youtube.com/embed/dQw4w9WgXcQ
- 带时间戳: https://youtu.be/dQw4w9WgXcQ?t=120
- 带其他参数: https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=share
- 移动端链接: https://m.youtube.com/watch?v=dQw4w9WgXcQ
- 无协议链接: youtube.com/watch?v=dQw4w9WgXcQ
- 仅视频ID: dQw4w9WgXcQ
"""
pattern = r'(?:youtube\.com\/(?:watch\?v=|embed\/|shorts\/|live\/)|youtu\.be\/)([^"&?\/\s]{11})'
match = re.search(pattern, url)
if match is None:
return None
video_id = match.group(1)
return video_id
def when_click_make_html_button(playlist: str):
urls = [url.strip() for url in playlist.split("\n") if url.strip()]
video_ids = [get_video_id(url) for url in urls]
video_ids = [video_id for video_id in video_ids if video_id is not None]
video_ids_ = json.dumps(video_ids, ensure_ascii=False)
template = Template(html_content)
variables = {
"video_ids": video_ids_
}
html_content_ = template.render(variables)
filename = make_file(html_content_)
return filename
def get_youtube_player_tab():
with gr.TabItem("youtube_player"):
with gr.Row():
with gr.Column(scale=5):
yp_playlist = gr.Textbox(
label="playlist",
value="https://www.youtube.com/watch?v=tvRNE-ULe94\nhttps://www.youtube.com/watch?v=VQmaDgmyIBc\nhttps://www.youtube.com/watch?v=e_sFLaQUN3k\nhttps://www.youtube.com/watch?v=-VDYnk0jM8Q",
placeholder="每行输入一个YouTube视频链接\n例如:\nhttps://www.youtube.com/watch?v=dQw4w9WgXcQ\nhttps://youtu.be/9bZkp7q19f0",
lines=10,
)
yp_make_html_button = gr.Button("make_html")
with gr.Column(scale=5):
yp_video_output = gr.File(label="play_html_file")
yp_make_html_button.click(
fn=when_click_make_html_button,
inputs=[yp_playlist],
outputs=[yp_video_output]
)
return locals()
if __name__ == "__main__":
with gr.Blocks() as block:
fs_components = get_youtube_player_tab()
block.launch()