Posts python3 如何只下载少量字节获取网络视频尺寸/帧数/帧率等信息
Post
Cancel

python3 如何只下载少量字节获取网络视频尺寸/帧数/帧率等信息

视频的尺寸/帧率等信息一般都在视频文件的头部几个字节内,所以只下载头部几个字节即可获得视频的尺寸/帧率等信息,不过具体也要看视频格式,有的格式会获取失败。

使用 opencv 获取视频尺寸/帧率等信息

1
2
3
4
5
6
7
8
9
10
11
12
13
import cv2

def get_source_info_opencv(source_name):
    try:
        cap = cv2.VideoCapture(source_name)
        width = cap.get(cv2.CAP_PROP_FRAME_WIDTH )
        height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
        fps = cap.get(cv2.CAP_PROP_FPS)
        num_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
        return (width, height, fps, num_frames)
    except Exception as e:
        print("read source:{} error. {}".format(source_name, e))
    return (0, 0, 0, 0)

使用 requests 下载数据流的同步版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import requests
import cv2

def get_source_info_opencv(source_name):
    try:
        cap = cv2.VideoCapture(source_name)
        width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
        height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
        fps = cap.get(cv2.CAP_PROP_FPS)
        num_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
        return (width, height, fps, num_frames)
    except Exception as e:
        print("read source:{} error. {}".format(source_name, e))
    return (0, 0, 0, 0)


def stream():
    # 用于保存视频头部字节流
    head_out_fp = 'out_head.mp4'
    # stream=True 表示数据流方式下载
    r = requests.get(
        'https://futurewindow.oss-cn-beijing.aliyuncs.com/other/2022/02/23/75600ec30a1948e083de84188dd73911.mp4', stream=True)
    # 每次下载的数据大小,经测试3KB左右,成功率较为理想
    chunk_size = 1024 * 3
    if r.status_code == 200:
        for chunk in r.iter_content(chunk_size):
            with open(head_out_fp, 'wb') as f:
                f.write(chunk)
            print(get_source_info_opencv(head_out_fp))
            r.close()

stream()
# 输出结果 (720.0, 400.0, 23.976023976023978, 260.0)

使用 aiohttp_requests 实现的异步版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from awaits.awaitable import awaitable
from aiohttp_requests import requests as io_requests
import asyncio
import cv2


@awaitable
def get_source_info_opencv(source_name):
    try:
        cap = cv2.VideoCapture(source_name)
        width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
        height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
        fps = cap.get(cv2.CAP_PROP_FPS)
        num_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
        return (width, height, fps, num_frames)
    except Exception as e:
        print("read source:{} error. {}".format(source_name, e))
    return (0, 0, 0, 0)


async def stream():
    # 用于保存视频头部字节流
    head_out_fp = 'out_head.mp4'
    url = 'https://futurewindow.oss-cn-beijing.aliyuncs.com/other/2022/02/23/75600ec30a1948e083de84188dd73911.mp4'
    # stream=True 表示数据流方式下载
    r = await io_requests.get(url)
    # 每次下载的数据大小,经测试3KB左右,成功率较为理想
    chunk_size = 1024 * 3
    if r.status == 200:
        async for chunk in r.content.iter_chunked(chunk_size):
            with open(head_out_fp, 'wb') as f:
                f.write(chunk)
            size = await get_source_info_opencv(head_out_fp)
            print(size)
            await r.wait_for_close()
            break

asyncio.run(stream())
# 输出结果 (720.0, 400.0, 23.976023976023978, 260.0)

邀请您关注我的公众号,我将会不时地为您推送独家原创的技术内容分享。
This post is licensed under CC BY 4.0 by the author.

Trending Tags