12.メモ
Views.py 20250427
from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.http import require_POST
from .forms import AppForm
from .models import App
import yt_dlp
from pathlib import Path
import os
from django.http import StreamingHttpResponse
import time
import threading
# 進捗バーを0.5秒おきに更新
progress = 0
def progress_stream(request):
def event_stream():
global progress
while progress < 100:
yield f"data: {progress}\n\n"
time.sleep(0.5)
yield f"data: 100\n\n"
return StreamingHttpResponse(event_stream(), content_type="text/event-stream")
# 進捗バーを0%にしてダウンロード開始
def download_video(url, format_choice):
global progress
progress = 0
download_path = str(Path.home() / "Downloads")
def progress_hook(d):
global progress
if d['status'] == 'downloading':
total = d.get('total_bytes') or d.get('total_bytes_estimate')
downloaded = d.get('downloaded_bytes', 0)
if total:
percent = downloaded / total * 100
progress = int(percent)
elif d['status'] == 'finished':
progress = 100
option = {
'outtmpl': os.path.join(download_path, '%(title)s.%(ext)s'),
'progress_hooks': [progress_hook],
}
if format_choice == 'mp4':
option['format'] = 'bestvideo+bestaudio/best'
option['merge_output_format'] = 'mp4'
elif format_choice == 'mp3':
option['format'] = 'bestaudio/best'
option['postprocessors'] = [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}]
elif format_choice == 'thumbnail':
option['writethumbnail'] = 'embed=thumbnail'
with yt_dlp.YoutubeDL(option) as yd:
yd.download([url])
def index(request):
global progress
if request.method == "POST":
form = AppForm(request.POST)
if form.is_valid():
saved = form.save()
url = saved.url
format_choice = form.cleaned_data['format']
# 新しいスレッドでダウンロードを開始
threading.Thread(target=download_video, args=(url, format_choice), daemon=True).start()
return render(request, 'app/index.html', {'form': AppForm()})
else:
form = AppForm()
return render(request, 'app/index.html', {'form': form})
def new(request):
return render(request, 'app/new.html')