|
import gradio as gr |
|
from moviepy.editor import VideoFileClip |
|
import cv2 |
|
import base64 |
|
from openai import OpenAI |
|
import os |
|
|
|
|
|
def process_video(video_path, seconds_per_frame=2): |
|
base64Frames = [] |
|
base_video_path, _ = os.path.splitext(video_path) |
|
video = cv2.VideoCapture(video_path) |
|
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) |
|
fps = video.get(cv2.CAP_PROP_FPS) |
|
frames_to_skip = int(fps * seconds_per_frame) |
|
curr_frame = 0 |
|
|
|
while curr_frame < total_frames - 1: |
|
video.set(cv2.CAP_PROP_POS_FRAMES, curr_frame) |
|
success, frame = video.read() |
|
if not success: |
|
break |
|
_, buffer = cv2.imencode(".jpg", frame) |
|
base64Frames.append(base64.b64encode(buffer).decode("utf-8")) |
|
curr_frame += frames_to_skip |
|
video.release() |
|
|
|
audio_path = f"{base_video_path}.mp3" |
|
clip = VideoFileClip(video_path) |
|
clip.audio.write_audiofile(audio_path, bitrate="32k") |
|
clip.audio.close() |
|
clip.close() |
|
|
|
return base64Frames, audio_path |
|
|
|
|
|
def summarize_video(api_key, file_path): |
|
client = OpenAI(api_key=api_key) |
|
|
|
|
|
base64Frames, audio_path = process_video(file_path, seconds_per_frame=0.5) |
|
|
|
|
|
transcription = client.audio.transcriptions.create( |
|
model="whisper-1", file=open(audio_path, "rb") |
|
) |
|
|
|
|
|
response = client.chat.completions.create( |
|
model="gpt-4o", |
|
messages=[ |
|
{ |
|
"role": "system", |
|
"content": """あなたは優秀な要約者です。提供された動画とその書き起こしの要約をMarkdown形式で作成してください""", |
|
}, |
|
{ |
|
"role": "user", |
|
"content": [ |
|
"これらは動画から取得されたフレームです", |
|
*map( |
|
lambda x: { |
|
"type": "image_url", |
|
"image_url": { |
|
"url": f"data:image/jpg;base64,{x}", |
|
"detail": "low", |
|
}, |
|
}, |
|
base64Frames, |
|
), |
|
{ |
|
"type": "text", |
|
"text": f"動画の書き起こしはこちらです: {transcription.text}", |
|
}, |
|
], |
|
}, |
|
], |
|
temperature=0, |
|
) |
|
|
|
return response.choices[0].message.content |
|
|
|
demo = gr.Interface( |
|
fn=summarize_video, |
|
inputs=[gr.Textbox(label="OpenAI API Key"), gr.File(label="Upload Video (mp4)")], |
|
outputs="markdown", |
|
title="Video Summarizer", |
|
description="動画をアップロードしOpenAIのAPIキーを入力し動画をアップロードすると要約が生成されます。API使用料にご注意ください。詳細: https://cookbook.openai.com/examples/gpt4o/introduction_to_gpt4o", |
|
) |
|
|
|
if __name__ == "__main__": |
|
demo.launch() |