2011-09-09 13 views
7

से वीडियो आयाम प्राप्त करना ffmpeg के सूचना आउटपुट से मुझे वीडियो की ऊंचाई और चौड़ाई कैसे प्राप्त होगी। उदाहरण के लिए, निम्न उत्पादन के साथ -ffmpeg -i

$ ffmpeg -i 1video.mp4 
... 

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/david/Desktop/1video.mp4': 
    Metadata: 
    major_brand  : isom 
    minor_version : 1 
    compatible_brands: isomavc1 
    creation_time : 2010-01-24 00:55:16 
    Duration: 00:00:35.08, start: 0.000000, bitrate: 354 kb/s 
    Stream #0.0(und): Video: h264 (High), yuv420p, 640x360 [PAR 1:1 DAR 16:9], 597 kb/s, 25 fps, 25 tbr, 25k tbn, 50 tbc 
    Metadata: 
     creation_time : 2010-01-24 00:55:16 
    Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16, 109 kb/s 
    Metadata: 
     creation_time : 2010-01-24 00:55:17 
At least one output file must be specified 

मैं कैसे height = 640, width= 360 मिलेंगे? धन्यवाद।

उत्तर

7

mediainfo पर एक नज़र डालें, वहां से अधिकांश प्रारूपों को संभालते हैं।

अजगर का उपयोग कर
$ ./ffmpeg -i test020.3gp 2>&1 | perl -lane 'print $1 if /(\d+x\d+)/' 
176x120 

उदाहरण (सही नहीं):

$ ./ffmpeg -i /nfshome/enilfre/pub/test020.3gp 2>&1 | python -c "import sys,re;[sys.stdout.write(str(re.findall(r'(\d+x\d+)', line))) for line in sys.stdin]" 

आप एक तरह से ffmpeg से उत्पादन पार्स करने के लिए की तलाश में हैं, तो regexp \d+x\d+

उदाहरण पर्ल का उपयोग कर का उपयोग

[] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] ['176x120'] [] [] []

अजगर एक-लाइनर्स पर्ल लोगों :-)

+0

बिल्कुल सही, आपको बहुत बहुत धन्यवाद। – David542

+1

यह परीक्षण करने में विफल रहता है, क्योंकि स्ट्रीम जानकारी 'स्ट्रीम # 0: 0: वीडियो: mjpeg (एमजेपीजी/0x47504A4D), yuvj420p (पीसी, बीटी 470 बीजी/अज्ञात/अज्ञात), 733x446 [एसएआर 1: 1 डीएआर 733: 446], 7516 केबी/एस, 60 एफपीएस, 60 टीआरबी, 60 टीबीएन, 60 टीबीसी', तो परिणाम '[] [] [] [] [] [] [] [] [] [] [] [] [] [] ['0x47504', '733x446'] [] ' –

3

ऊपर फ्रेड्रिक के टिप से के रूप में के रूप में आकर्षक नहीं हैं, यहाँ है मैं इसे कैसे MediaInfo (http://mediainfo.sourceforge.net/en) का उपयोग किया:

>>> p1 = subprocess.Popen(['mediainfo', '--Inform=Video;%Width%x%Height%',   
    '/Users/david/Desktop/10stest720p.mov'],stdout=PIPE) 
>>> dimensions=p1.communicate()[0].strip('\n') 
>>> dimensions 
'1280x688' 
3

this blog post में एक किसी न किसी समाधान theres पायथन में:

import subprocess, re 
pattern = re.compile(r'Stream.*Video.*([0-9]{3,})x([0-9]{3,})') 

def get_size(pathtovideo): 
    p = subprocess.Popen(['ffmpeg', '-i', pathtovideo], 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE) 
    stdout, stderr = p.communicate() 
    match = pattern.search(stderr) 
    if match: 
     x, y = map(int, match.groups()[0:2]) 
    else: 
     x = y = 0 
    return x, y 

हालांकि यह मानता है कि यह 3 अंकों x 3 अंक (यानी और

possible_patterns = [re.compile(r'Stream.*Video.*([0-9]{4,})x([0-9]{4,})'), \ 
      re.compile(r'Stream.*Video.*([0-9]{4,})x([0-9]{3,})'), \ 
re.compile(r'Stream.*Video.*([0-9]{3,})x([0-9]{3,})')] 

जाँच करता है, तो मैच हर कदम पर कोई नहीं देता है: 854x480), तो आप इस तरह के रूप (1280x720 संभव आयाम लंबाई,) के माध्यम से लूप करने की आवश्यकता होगी

for pattern in possible_patterns: 
    match = pattern.search(stderr) 
    if match!=None: 
     x, y = map(int, match.groups()[0:2]) 
     break 

if match == None: 
    print "COULD NOT GET VIDEO DIMENSIONS" 
    x = y = 0 

return '%sx%s' % (x, y) 

खूबसूरत हो सकता है, लेकिन काम करता है।

1

खराब (\ d + x \ घ +)

$ echo 'Stream #0:0(eng): Video: mjpeg (jpeg/0x6765706A), yuvj420p, 1280x720, 19939 kb/s, 30 fps, 30 tbr, 30 tbn, 30 tbc' | perl -lane 'print $1 if /(\d+x\d+)/' 
> 0x6765706 

अच्छा ([0-9] {2,} एक्स [0-9] +)

$ echo 'Stream #0:0(eng): Video: mjpeg (jpeg/0x6765706A), yuvj420p, 1280x720, 19939 kb/s, 30 fps, 30 tbr, 30 tbn, 30 tbc' | perl -lane 'print $1 if /([0-9]{2,}x[0-9]+)/' 
> 1280x720 
+0

या (\ d {2,} x \ d +) –

0

मॉड्यूल

फिर बिना
out = error_message.split()    # make a list from resulting error string 
out.reverse() 
for index, item in enumerate(out):  # extract the item before item= "[PAR" 
    if item == "[PAR":      # 
     dimension_string = out[i+1]   # 
     video_width, video_height = dimension_string.split("x") 

संपादित करें: नहीं एक अच्छा जवाब नहीं है क्योंकि सभी वीडियो है कि "बराबर" जानकारी :(

1

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

मेरा प्रयास यहां है। यह "एक-लाइनर" की तुलना में वर्बोज़ है, लेकिन ऐसा इसलिए है क्योंकि मैं जानना चाहता हूं कि आखिरकार यह विफल क्यों होता है।

import subprocess 

def get_video_size(video_filename): 
    """Returns width, height of video using ffprobe""" 
    # Video duration and hence start time 
    proc = subprocess.Popen(['ffprobe', video_filename], 
     stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
    res = proc.communicate()[0] 

    # Check if ffprobe failed, probably on a bad file 
    if 'Invalid data found when processing input' in res: 
     raise ValueError("Invalid data found by ffprobe in %s" % video_filename) 

    # Find the video stream 
    width_height_l = [] 
    for line in res.split("\n"): 
     # Skip lines that aren't stream info 
     if not line.strip().startswith("Stream #"): 
      continue 

     # Check that this is a video stream 
     comma_split = line.split(',') 
     if " Video: " not in comma_split[0]: 
      continue 

     # The third group should contain the size and aspect ratio 
     if len(comma_split) < 3: 
      raise ValueError("malform video stream string:", line) 

     # The third group should contain the size and aspect, separated 
     # by spaces 
     size_and_aspect = comma_split[2].split()   
     if len(size_and_aspect) == 0: 
      raise ValueError("malformed size/aspect:", comma_split[2]) 
     size_string = size_and_aspect[0] 

     # The size should be two numbers separated by x 
     width_height = size_string.split('x') 
     if len(width_height) != 2: 
      raise ValueError("malformed size string:", size_string) 

     # Cast to int 
     width_height_l.append(map(int, width_height)) 

    if len(width_height_l) > 1: 
     print "warning: multiple video streams found, returning first" 
    return width_height_l[0] 
29

उपयोग ffprobe:

$ ffprobe -v error -show_entries stream=width,height \ 
    -of default=noprint_wrappers=1 input.mp4 
width=1280 
height=720 

क्या विकल्प कार्य करें:

  • -v error एक शांत उत्पादन बनाओ, लेकिन त्रुटियों प्रदर्शित करने के लिए अनुमति देते हैं। संस्करण, कॉन्फ़िगरेशन और इनपुट विवरण सहित सामान्य सामान्य FFmpeg आउटपुट जानकारी को छोड़कर।

  • -show_entries stream=width,height बस width और height स्ट्रीम जानकारी दिखाएं।

  • -of default=noprint_wrappers=1 यह [STREAM]...[/STREAM] रैपर को छोड़ देगा जो आम तौर पर आउटपुट में दिखाए जाएंगे। यदि आप width= और height= कुंजी को भी छोड़ना चाहते हैं, तो -of default=noprint_wrappers=1:nokey=1 का उपयोग करें।

  • अन्य आउटपुट प्रारूप विकल्प आपकी आवश्यकताओं के अनुरूप उपलब्ध हैं। इन्हें -of (उर्फ -print_format) विकल्प के माध्यम से सेट किया जा सकता है, और प्रारूप हैं: डिफ़ॉल्ट, कॉम्पैक्ट, सीएसवी, फ्लैट, आईएनआई, जेसन, एक्सएमएल। प्रत्येक प्रारूप के विवरण के लिए FFprobe Documentation: Writers देखें और अतिरिक्त विकल्प देखने के लिए।

  • -select_streams v:0 यदि आपके इनपुट में एकाधिक वीडियो स्ट्रीम शामिल हैं तो इसे जोड़ा जा सकता है। v:0 केवल पहली वीडियो स्ट्रीम का चयन करेगा। अन्यथा आपको वीडियो स्ट्रीम के रूप में width और height आउटपुट प्राप्त होंगे।

  • अधिक जानकारी के लिए FFprobe Documentation और FFmpeg Wiki: FFprobe Tips देखें।

+0

यह सहायक है, लेकिन मुझे लगता है कि ओपी पायथन में मानों को कैप्चर करना चाहता था। – Geoff

+0

@Geoff यह आवश्यक मान प्रदान करेगा, और यहां दिखाए गए अन्य तरीके से अधिक विश्वसनीय होगा। पाइथन के साथ इसका उपयोग कैसे किया जाता है उपयोगकर्ता तक। वास्तव में – LordNeckbeard

+0

। इसने मेरी बहुत मदद की। धन्यवाद। आउटपुट कैप्चर करने के लिए 'subprocess' पैकेज का उपयोग करके' re.search' के साथ पार्स करना बहुत आसान है। नकारात्मक ध्वनि के लिए खेद है। – Geoff

2

यहाँ उल्लेख किया है, ffprobe एक वीडियो फ़ाइल के बारे में डेटा पुन: प्राप्त करने का एक तरीका प्रदान करता है। मुझे निम्न आदेश उपयोगी ffprobe -v quiet -print_format json -show_streams input-video.xxx मिला है यह देखने के लिए कि आप किस प्रकार का डेटा चेकआउट कर सकते हैं।

मैं तो एक समारोह है कि उपरोक्त आदेश चलाता है और ऊंचाई वीडियो फ़ाइल की चौड़ाई रिटर्न लिखा है:

import subprocess 
import shlex 
import json 

# function to find the resolution of the input video file 
def findVideoResolution(pathToInputVideo): 
    cmd = "ffprobe -v quiet -print_format json -show_streams" 
    args = shlex.split(cmd) 
    args.append(pathToInputVideo) 
    # run the ffprobe process, decode stdout into utf-8 & convert to JSON 
    ffprobeOutput = subprocess.check_output(args).decode('utf-8') 
    ffprobeOutput = json.loads(ffprobeOutput) 

    # find height and width 
    height = ffprobeOutput['streams'][0]['height'] 
    width = ffprobeOutput['streams'][0]['width'] 

    return height, width