获取视频文件的尺寸

37
有没有办法在Python中获取视频文件的尺寸,或者其他可以实现这一功能的库?类似于“媒体信息”之类的东西吗?

Pygame中的视频模块应该可以正常工作。 - Jace Browning
Pygame中的视频模块应该可以正常工作。 - undefined
9个回答

40

如果我理解正确,您指的是例如视频的分辨率(768x432)。

这可以简单地通过Python中的OpenCV来完成。

import cv2
file_path = "./video.avi"  # change to your own video path
vid = cv2.VideoCapture(file_path)
height = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
width = vid.get(cv2.CAP_PROP_FRAME_WIDTH)

这应该是被接受的答案。 - Seth

17

使用ffmpeg-python怎么样:

import ffmpeg
probe = ffmpeg.probe(movie_path)
video_streams = [stream for stream in probe["streams"] if stream["codec_type"] == "video"]

它会给你这样一个非常漂亮的输出:

>>> import pprint
>>> pprint.pprint(video_streams[0])
{'avg_frame_rate': '30/1',
 'bit_rate': '3291',
 'bits_per_raw_sample': '8',
 'chroma_location': 'left',
 'codec_long_name': 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10',
 'codec_name': 'h264',
 'codec_tag': '0x31637661',
 'codec_tag_string': 'avc1',
 'codec_time_base': '1/60',
 'codec_type': 'video',
 'coded_height': 240,
 'coded_width': 320,
 'color_primaries': 'bt709',
 'color_range': 'tv',
 'color_space': 'bt709',
 'color_transfer': 'bt709',
 'display_aspect_ratio': '4:3',
 'disposition': {'attached_pic': 0,
                 'clean_effects': 0,
                 'comment': 0,
                 'default': 1,
                 'dub': 0,
                 'forced': 0,
                 'hearing_impaired': 0,
                 'karaoke': 0,
                 'lyrics': 0,
                 'original': 0,
                 'timed_thumbnails': 0,
                 'visual_impaired': 0},
 'duration': '71.833333',
 'duration_ts': 6465000,
 'field_order': 'progressive',
 'has_b_frames': 1,
 'height': 240,
 'index': 0,
 'is_avc': 'true',
 'level': 13,
 'nal_length_size': '4',
 'pix_fmt': 'yuv420p',
 'profile': 'Main',
 'r_frame_rate': '30/1',
 'refs': 1,
 'sample_aspect_ratio': '1:1',
 'start_pts': 0,
 'start_time': '0.000000',
 'tags': {'creation_time': '2018-10-26T04:25:07.000000Z',
          'handler_name': 'VideoHandler',
          'language': 'und'},
 'time_base': '1/90000',
 'width': 320}

唯一的缺点是需要使用ffmpeg,但在大多数情况下这不应该成为问题。


4
实际上,有一种更好的方法来完成这个任务。你不需要使用列表推导式: video_streams = ffmpeg.probe(movie_path, select_streams = "v") 就足够了。 - Georgi Stoyanov
属性错误:模块 'ffmpeg' 没有 'probe' 属性?? - undefined
没关系,我找到答案了。先运行PIP uninstall ffmpeg,然后再运行PIP Install ffmpeg-python。 - undefined

6
在我上一个公司也遇到了类似的问题,但我找不到任何 Python 库来解决它。所以我最终在 Python 中使用了来自 mediainfo 的工具,Media Info 也有一个命令行选项,非常容易解析其输出,因此你的 Python 模块可以使用 Media Info ,这将足够满足需求。它还有进一步的优点,因为最终你会发现并不是所有的媒体信息类型软件都支持所有编解码器/格式,所以你可以在单个 Python 封装下使用多个软件/库。

你不需要启动一个进程来做这个,参见我在这里的回答 - Janus Troelsen

4
这个库的主页上似乎有一个示例可以实现这个功能(print_info(vs)):http://code.google.com/p/ffvideo/。它是ffmpeg的一个包装器(似乎有几个Python库可用于使用ffmpeg)。

3
无法编译,似乎已停止维护。 - Darioush

3
您可以使用一个纯Python工具 hachoir-metadata 来实现:
#!/usr/bin/env python
"""Get dimensions of a video file.

Usage: get-video-dimensions <video-file>
"""
import sys
from itertools import chain

from hachoir_core.cmd_line import unicodeFilename
from hachoir_metadata import extractMetadata
from hachoir_parser import createParser

if len(sys.argv) != 2:
    sys.exit(__doc__)

file_metadata = extractMetadata(createParser(unicodeFilename(sys.argv[1])))
print("%sx%s" % next((metadata.get('width'), metadata.get('height'))
                     for metadata in chain([file_metadata], file_metadata.iterGroups())
                     if metadata.has('width') and metadata.get('height')))

安装步骤:

$ pip install hachoir-{core,parser,metadata}

1
对于那些后来遇到这个问题的人,需要注意的是 - Python 3 的 hachoir 是一个不同的包:http://hachoir3.readthedocs.io/install.html - pip install hachoir3 - Nick
这些都不起作用。Nick的评论和原始答案都无效。无法安装hachoir。 - Seth
@Seth,你可以从这里开始 https://pypi.org/project/hachoir/(很可能,答案中的代码可以简化为该版本)。 - jfs
@jfs,下面这个回答是正确的。它只是使用了CV2。 - Seth
@Seth:没有“正确”的答案。最好的解决方案取决于具体情况(例如,纯Python解决方案可以更轻松地安装在更多平台上)。 - jfs

2

有一个名为pymediainfo的Python模块-https://pypi.org/project/pymediainfo/,您可以使用它来获取媒体文件所需的元数据。

创建一个目录。

mkdir supportfiles

由于某些原因,我将模块安装在名为“supportfiles”的目标目录中。
pip install pymediainfo -t supportfiles/

获取视频文件的尺寸/分辨率

resolution.py

from supportfiles.pymediainfo import MediaInfo
media_info = MediaInfo.parse('/home/sathish/Videos/Aandipatti.mp4')

for track in media_info.tracks:
    if track.track_type == 'Video':
        print ("Resolution {}x{}".format(track.width, track.height))

以下是输出结果

[sathish@localhost test]$ python3.6 resolution.py 
Resolution 1920x1080

如果您想知道元数据属性列表,这里是解决方案。

attributes.py

from supportfiles.pymediainfo import MediaInfo
media_info = MediaInfo.parse('/home/sathish/Videos/Aandipatti.mp4')
print(media_info.tracks)
for track in media_info.tracks:
    if track.track_type == 'Video':
        print(track.to_data().keys())
    elif track.track_type == 'Audio':
        print(track.to_data().keys())
    elif track.track_type == 'General':
        print(track.to_data().keys())
    else:
        print("No metadata present! or probably file corrupt!")

以下是属性列表

[sathish@localhost test]$ python3.6 attributes.py 
[<Track track_id='None', track_type='General'>, <Track track_id='1', track_type='Video'>, <Track track_id='2', track_type='Audio'>]

dict_keys(['track_type', 'count', 'count_of_stream_of_this_kind', 'kind_of_stream', 'other_kind_of_stream', 'stream_identifier', 'count_of_video_streams', 'count_of_audio_streams', 'video_format_list', 'video_format_withhint_list', 'codecs_video', 'audio_format_list', 'audio_format_withhint_list', 'audio_codecs', 'complete_name', 'folder_name', 'file_name', 'file_extension', 'format', 'other_format', 'format_extensions_usually_used', 'commercial_name', 'format_profile', 'internet_media_type', 'codec_id', 'other_codec_id', 'codec_id_url', 'codecid_compatible', 'codec', 'other_codec', 'codec_extensions_usually_used', 'file_size', 'other_file_size', 'duration', 'other_duration', 'overall_bit_rate', 'other_overall_bit_rate', 'frame_rate', 'other_frame_rate', 'frame_count', 'stream_size', 'other_stream_size', 'proportion_of_this_stream', 'headersize', 'datasize', 'footersize', 'isstreamable', 'file_last_modification_date', 'file_last_modification_date__local', 'writing_application', 'other_writing_application'])

dict_keys(['track_type', 'count', 'count_of_stream_of_this_kind', 'kind_of_stream', 'other_kind_of_stream', 'stream_identifier', 'streamorder', 'track_id', 'other_track_id', 'format', 'format_info', 'format_url', 'commercial_name', 'format_profile', 'format_settings', 'format_settings__cabac', 'other_format_settings__cabac', 'format_settings__reframes', 'other_format_settings__reframes', 'internet_media_type', 'codec_id', 'codec_id_info', 'codec', 'other_codec', 'codec_family', 'codec_info', 'codec_url', 'codec_cc', 'codec_profile', 'codec_settings', 'codec_settings__cabac', 'codec_settings_refframes', 'duration', 'other_duration', 'duration_firstframe', 'other_duration_firstframe', 'bit_rate', 'other_bit_rate', 'width', 'other_width', 'height', 'other_height', 'stored_height', 'sampled_width', 'sampled_height', 'pixel_aspect_ratio', 'display_aspect_ratio', 'other_display_aspect_ratio', 'rotation', 'frame_rate_mode', 'other_frame_rate_mode', 'frame_rate', 'other_frame_rate', 'minimum_frame_rate', 'other_minimum_frame_rate', 'maximum_frame_rate', 'other_maximum_frame_rate', 'frame_count', 'resolution', 'other_resolution', 'colorimetry', 'color_space', 'chroma_subsampling', 'other_chroma_subsampling', 'bit_depth', 'other_bit_depth', 'scan_type', 'other_scan_type', 'interlacement', 'other_interlacement', 'bits__pixel_frame', 'stream_size', 'other_stream_size', 'proportion_of_this_stream', 'color_range', 'colour_description_present', 'color_primaries', 'transfer_characteristics', 'matrix_coefficients'])

dict_keys(['track_type', 'count', 'count_of_stream_of_this_kind', 'kind_of_stream', 'other_kind_of_stream', 'stream_identifier', 'streamorder', 'track_id', 'other_track_id', 'format', 'format_info', 'commercial_name', 'format_profile', 'codec_id', 'codec', 'other_codec', 'codec_family', 'codec_cc', 'duration', 'other_duration', 'bit_rate_mode', 'other_bit_rate_mode', 'bit_rate', 'other_bit_rate', 'channel_s', 'other_channel_s', 'channel_positions', 'other_channel_positions', 'channellayout', 'samples_per_frame', 'sampling_rate', 'other_sampling_rate', 'samples_count', 'frame_rate', 'other_frame_rate', 'frame_count', 'compression_mode', 'other_compression_mode', 'stream_size', 'other_stream_size', 'proportion_of_this_stream', 'default', 'other_default', 'alternate_group', 'other_alternate_group'])

希望这对你有所帮助!


0

你也可以直接从Windows元数据中获取尺寸:

import win32com.client
def get_dimensions(path,file):
    sh = win32com.client.gencache.EnsureDispatch('Shell.Application', 0)
    ns = sh.NameSpace(path)
    item = ns.ParseName(file)
    height = ns.GetDetailsOf(item,314)
    width = ns.GetDetailsOf(item,316)
    return [height, width]

dimensions = get_dimensions("C:\folder","video.avi")

要获取所有可用属性的完整概述,您可以尝试:

attributes_list = []
for i in range(330):
    attributes_list.append([ns.GetDetailsOf("",i), ns.GetDetailsOf(item,i)])
print(attributes_list)

0

Pygame中的视频模块应该可以工作。


-16
旧问题,但是... 要获取文件的大小:
file_size_in_Mio = os.path.getsize(name_of_video) //(1024*1024)

3
尺寸 = 宽度 x 高度 - Lucas
我认为你没有仔细阅读问题。请考虑改进或删除此回答。 - Geoff
以下是有关编程的内容,请将其翻译成中文。请仅返回已翻译的文字: - microchip78

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接