|
18 | 18 |
|
19 | 19 | import os |
20 | 20 | import ffmpeg |
21 | | -from services.file_management import download_file |
22 | 21 | from config import LOCAL_STORAGE_PATH |
23 | 22 |
|
24 | 23 | def extract_thumbnail(video_url, job_id, second=0): |
25 | 24 | """ |
26 | 25 | Extract a thumbnail from a video at the specified timestamp. |
27 | | - |
| 26 | + Uses ffmpeg direct streaming to avoid downloading the entire video file. |
| 27 | +
|
28 | 28 | Args: |
29 | 29 | video_url (str): URL of the video to extract thumbnail from |
30 | 30 | job_id (str): Unique identifier for the job |
31 | 31 | second (float): Timestamp in seconds to extract the thumbnail from (default: 0) |
32 | | - |
| 32 | +
|
33 | 33 | Returns: |
34 | 34 | str: Path to the extracted thumbnail image |
35 | 35 | """ |
36 | | - # Download the video from the provided URL |
37 | | - video_path = download_file(video_url, os.path.join(LOCAL_STORAGE_PATH, f"{job_id}_input")) |
38 | | - |
39 | 36 | # Set output path for the thumbnail |
40 | 37 | thumbnail_path = os.path.join(LOCAL_STORAGE_PATH, f"{job_id}_thumbnail.jpg") |
41 | | - |
| 38 | + |
42 | 39 | try: |
43 | | - # Extract thumbnail using ffmpeg at the specified timestamp |
| 40 | + # Extract thumbnail directly from URL using ffmpeg streaming |
| 41 | + # analyzeduration and probesize are set low to reduce initial buffering |
44 | 42 | ( |
45 | 43 | ffmpeg |
46 | | - .input(video_path, ss=second) # 'ss' is the seek parameter for the timestamp |
47 | | - .output(thumbnail_path, vframes=1) # vframes=1 extracts a single frame |
| 44 | + .input(video_url, ss=second, analyzeduration='100K', probesize='100K') |
| 45 | + .output(thumbnail_path, vframes=1, update=1) |
48 | 46 | .overwrite_output() |
49 | 47 | .run(capture_stdout=True, capture_stderr=True) |
50 | 48 | ) |
51 | | - |
52 | | - # Clean up the downloaded video file |
53 | | - os.remove(video_path) |
54 | | - |
| 49 | + |
55 | 50 | # Ensure the thumbnail file exists |
56 | 51 | if not os.path.exists(thumbnail_path): |
57 | 52 | raise FileNotFoundError(f"Thumbnail file {thumbnail_path} was not created") |
58 | | - |
| 53 | + |
59 | 54 | return thumbnail_path |
60 | | - |
| 55 | + |
61 | 56 | except Exception as e: |
62 | 57 | print(f"Thumbnail extraction failed: {str(e)}") |
63 | | - # Clean up any downloaded files on error |
64 | | - if os.path.exists(video_path): |
65 | | - os.remove(video_path) |
| 58 | + # Clean up partial thumbnail file on error |
| 59 | + if os.path.exists(thumbnail_path): |
| 60 | + os.remove(thumbnail_path) |
66 | 61 | raise |
0 commit comments