मुझे एल्गोरिदम पर काम करने के लिए एक ऑनलाइन वीडियो के विशिष्ट फ़्रेम निकालने की आवश्यकता है, लेकिन मैं पूरा वीडियो डाउनलोड नहीं करना चाहता क्योंकि इससे यह अत्यधिक अक्षम हो जाएगा।

शुरुआत के लिए, मैंने यूट्यूब वीडियो के साथ काम करने की कोशिश की। मैं इस तरह से youtube-dl का उपयोग करके पूरा वीडियो डाउनलोड कर सकता हूं:

ydl_opts = {'outtmpl': r'OUTPUT_DIRECTORY_HERE',}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    ydl.download([url])

और फिर मैं अलग-अलग फ्रेम कैप्चर कर सकता हूं।

मुझे पूरा वीडियो डाउनलोड करने से बचना चाहिए। कुछ शोध के बाद, मैंने पाया है कि ffmpeg ऐसा करने में मेरी मदद कर सकता है। मुझे केवल फ़्रेम डाउनलोड करने का कोई तरीका नहीं मिला, इसलिए यदि यह संभव नहीं है, तो दूसरा विकल्प यह है कि मैं वीडियो के विशिष्ट भाग डाउनलोड कर सकता हूं। लिनक्स में ऐसा ही एक उदाहरण है यहाँ लेकिन मुझे अजगर के लिए कोई समाधान नहीं मिला।

पूरी चीज को डाउनलोड किए बिना सिर्फ फ्रेम, या वीडियो के हिस्से (पायथन में) डाउनलोड करने का एक अच्छा तरीका क्या है?

2
Kashish Arora 19 फरवरी 2021, 09:30

2 जवाब

सबसे बढ़िया उत्तर

वर्तमान उत्तर में जोड़ने के लिए, मल्टीप्रोसेसिंग का उपयोग करके प्रदर्शन को और बढ़ाया जा सकता है। उदाहरण के लिए, यदि आप वीडियो को फ़्रेम में विभाजित करना चाहते हैं और उन्हें num_cpu प्रक्रियाओं में स्वतंत्र रूप से संसाधित करना चाहते हैं:

import os
from functools import partial
from multiprocessing.pool import Pool

import cv2
import youtube_dl

def process_video_parallel(url, skip_frames, process_number):
    cap = cv2.VideoCapture(url)
    num_processes = os.cpu_count()
    frames_per_process = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) // num_processes
    cap.set(cv2.CAP_PROP_POS_FRAMES, frames_per_process * process_number)
    x = 0
    count = 0
    while x < 10 and count < frames_per_process:
        ret, frame = cap.read()
        if not ret:
            break
        filename =r"PATH\shot"+str(x)+".png"
        x += 1
        cv2.imwrite(filename.format(count), frame)
        count += skip_frames  # Skip 300 frames i.e. 10 seconds for 30 fps
        cap.set(1, count)
    cap.release()



video_url = "..."  # The Youtube URL
ydl_opts = {}
ydl = youtube_dl.YoutubeDL(ydl_opts)
info_dict = ydl.extract_info(video_url, download=False)

formats = info_dict.get('formats', None)

print("Obtaining frames")
for f in formats:
    if f.get('format_note', None) == '144p':
        url = f.get('url', None)
        cpu_count = os.cpu_count()
        with Pool(cpu_count) as pool:
            pool.map(partial(process_video_parallel, url, 300), range(cpu_count))

इस एप्लिकेशन के प्रयोजनों के लिए, चूंकि छवियों को केवल वीडियो से सहेजा जा रहा है, इसका परिणाम बहुत बड़ा सुधार (शायद कुछ सेकंड) में नहीं हो सकता है, लेकिन यदि फ़्रेम पर अतिरिक्त एल्गोरिदम लागू करने की आवश्यकता है, तो यह फायदेमंद हो सकता है।

4
danielcahall 4 मार्च 2021, 05:22

मैंने कोशिश की कि @AyeshaKhan ने टिप्पणियों में क्या साझा किया।

cv2,numpy,youtube-dl आयात करने के बाद:


    url=saved_url #The Youtube URL
    ydl_opts={}
    ydl=youtube_dl.YoutubeDL(ydl_opts)
    info_dict=ydl.extract_info(video_url, download=False)

    formats = info_dict.get('formats',None)
    print("Obtaining frames")
    for f in formats:
        if f.get('format_note',None) == '144p':
            url = f.get('url',None)
            cap = cv2.VideoCapture(url)
            x=0
            count=0
            while x<10:
                ret, frame = cap.read()
                if not ret:
                    break
                filename =r"PATH\shot"+str(x)+".png"
                x+=1
                cv2.imwrite(filename.format(count), frame)
                count+=300 #Skip 300 frames i.e. 10 seconds for 30 fps
                cap.set(1,count)
                if cv2.waitKey(30)&0xFF == ord('q'):
                    break
            cap.release()

टिप्पणियों में उत्तर सभी फ़्रेमों को डाउनलोड कर रहा था इसलिए count मैंने .format() में जोड़ा यह सुनिश्चित किया कि मैंने अपनी आवश्यकता के अनुसार फ़्रेम को छोड़ दिया।

इसके अतिरिक्त, x यहां संख्या को 10 तक सीमित करता है।

हालांकि, मुझे अभी भी यकीन नहीं है कि क्या यह विधि वास्तव में निर्दिष्ट फ़्रेमों को कैप्चर कर रही है, या यदि यह सभी फ़्रेमों को कैप्चर कर रही है और केवल निर्दिष्ट फ़्रेम को मेरे स्थानीय संग्रहण में सहेज रही है। मुझे पहले वाली चीज चाहिए थी।

लेकिन यह अभी भी काफी तेज है और मेरे लिए काम करता है!

0
Kashish Arora 4 मार्च 2021, 14:52