10

I can use the advanced options in YouTube or Google when searching for video clip, but I can only search for a pre-defined range of duration (short, long), not the duration that I want. For example, how can I search for every clip that has a duration between 30 seconds and 150 seconds?

0

2 Answers 2

3

I wrote a program that utilized YouTube Data API that does the job:

#!/usr/bin/env python3
# pip install google-api-python-client
import googleapiclient.discovery
from functools import reduce
import re

def iso_time_duration_to_seconds(duration_iso: str) -> int:
    pattern = 'PT((?P<hours>\d{1,2})H)?((?P<minutes>\d{1,2})M)?((?P<seconds>\d{1,2})S)?'
    m = re.fullmatch(pattern, duration_iso)
    video_duration_seconds = reduce(lambda l, r: int(l)*60+int(r), m.groupdict(default=0).values())
    return video_duration_seconds

def search_youtube_videos(target_duration_iso, search_query, maxResults=100):
    api_key = "YOUR_YOUTUBE_API_KEY"  # Replace with your YouTube API key
    youtube = googleapiclient.discovery.build("youtube", "v3", developerKey=api_key)

    # Categorize YouTube video duration
    target_video_duration_seconds = iso_time_duration_to_seconds(target_duration_iso)
    if target_video_duration_seconds < iso_time_duration_to_seconds('PT4M'):
        videoDuration = 'short'
    elif target_video_duration_seconds < iso_time_duration_to_seconds('PT20M'):
        videoDuration = 'medium'
    else:
        videoDuration = 'long'
    search_response = youtube.search().list(
        q=search_query,
        part="id,snippet",
        type="video",
        videoDuration=videoDuration,
        maxResults=maxResults
    ).execute()

    for search_result in search_response.get("items", []):
        video_id = search_result["id"]["videoId"]
        video_title = search_result["snippet"]["title"]
        duration_iso = get_video_duration(video_id, youtube)
        if duration_iso == target_duration_iso:
            print(f"Video Title: {video_title}")
            print(f"Video ID: {video_id}")
            print(f"Video Duration (ISO): {duration_iso}")

def get_video_duration(video_id, youtube):
    video_response = youtube.videos().list(
        part="contentDetails",
        id=video_id
    ).execute()
    duration_iso = video_response["items"][0]["contentDetails"]["duration"]
    return duration_iso

if __name__ == "__main__":
    target_duration_iso = 'PT14M7S' # ISO 8601 time duration
    search_query = '00:14:07'
    maxResults = 100
    search_youtube_videos(target_duration_iso, search_query, maxResults)

The abbreviated script above only accepts time duration in ISO 8601 format

For complete set of features, visit following repo: https://github.com/WingTillDie/youtube-video-length

It includes:

  • Also accepts time duration specified in seconds
  • Assertions that checks input ISO 8601 time duration format is correct for YouTube (not 0-padded)
  • List feature that doesn't filter by video duration
0
4

There's no way to specify an exact duration in the generic YouTube search other than their default short and long durations.

The only place on YouTube you can do this is on your video manager page, which manages your personal videos. As the docs say, you can search using length[operator][time] where [operator] can be >, >=, =, <=, or < and [time] is an integer in seconds. This generates a URL such as https://www.youtube.com/my_videos?o=U&sq=length%3E30+length%3C150 using the seconds you gave in the question.

I tried using this same query format in the URL of a regular YouTube search (thinking perhaps it's not in the UI but may still be allowed) but it didn't filter the search any more. That means it's not possible in the generic search.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.