python - 如何定位视频子集的时间戳

标签 python opencv video ffmpeg mp4

我以前从未做过任何基于视频的编程,虽然 this SuperUser post 提供了一种在命令行上完成的方法,但我更喜欢编程方法,最好是使用 Python。

我有一堆子视频。假设其中一个称为 1234_trimmed.mp4,它是从原始的、更长的视频 1234.mp4 中截取的一小段。 如何计算 1234.mp4 中 1234_trimmed.mp4 的开始和结束时间戳?

仅供引用,如果有任何快捷方式,这些视频无论如何都最初在 YouTube 上(“1234”对应于 YouTube 视频 ID)。

最佳答案

我自己用 cv2 弄清楚了.我的策略是获取子视频的第一帧和最后一帧,并遍历原始视频的每一帧,在这里我将当前帧的 dhash(最小汉明距离,而不是在调整大小和其他转换的情况下检查是否相等)与第一帧进行比较和最后一帧。我敢肯定可能会有一些优化机会,但我昨天需要这个。

import cv2

original_video_fpath = '5 POPULAR iNSTAGRAM BEAUTY TRENDS (DiY Feather Eyebrows, Colored Mascara, Drippy Lips, Etc)-vsNVU7y6dUE.mp4'
subvideo_fpath = 'vsNVU7y6dUE_trimmed-out.mp4'


def dhash(image, hashSize=8):
    # resize the input image, adding a single column (width) so we
    # can compute the horizontal gradient
    resized = cv2.resize(image, (hashSize + 1, hashSize))
    # compute the (relative) horizontal gradient between adjacent
    # column pixels
    diff = resized[:, 1:] > resized[:, :-1]
    # convert the difference image to a hash
    return sum([2 ** i for (i, v) in enumerate(diff.flatten()) if v])


def hamming(a, b):
    return bin(a^b).count('1')


def get_video_frame_by_index(video_cap, frame_index):
    # get total number of frames
    totalFrames = video_cap.get(cv2.CAP_PROP_FRAME_COUNT)

    if frame_index < 0:
        frame_index = int(totalFrames) + frame_index

    # check for valid frame number
    if frame_index >= 0 & frame_index <= totalFrames:
        # set frame position
        video_cap.set(cv2.CAP_PROP_POS_FRAMES, frame_index)

    _, frame = video_cap.read()
    return frame


def main():
    cap_original_video = cv2.VideoCapture(original_video_fpath)

    cap_subvideo = cv2.VideoCapture(subvideo_fpath)

    first_frame_subvideo = get_video_frame_by_index(cap_subvideo, 0)
    last_frame_subvideo = get_video_frame_by_index(cap_subvideo, -1)

    first_frame_subvideo_gray = cv2.cvtColor(first_frame_subvideo, cv2.COLOR_BGR2GRAY)
    last_frame_subvideo_gray = cv2.cvtColor(last_frame_subvideo, cv2.COLOR_BGR2GRAY)

    hash_first_frame_subvideo = dhash(first_frame_subvideo)
    hash_last_frame_subvideo = dhash(last_frame_subvideo)

    min_hamming_dist_with_first_frame = float('inf')
    closest_frame_index_first = None
    closest_frame_timestamp_first = None

    min_hamming_dist_with_last_frame = float('inf')
    closest_frame_index_last = None
    closest_frame_timestamp_last = None

    frame_index = 0
    while(cap_original_video.isOpened()):
        frame_exists, curr_frame = cap_original_video.read()

        if frame_exists:
            timestamp = cap_original_video.get(cv2.CAP_PROP_POS_MSEC) // 1000

            hash_curr_frame = dhash(curr_frame)

            hamming_dist_with_first_frame = hamming(hash_curr_frame, hash_first_frame_subvideo)
            hamming_dist_with_last_frame = hamming(hash_curr_frame, hash_last_frame_subvideo)

            if hamming_dist_with_first_frame < min_hamming_dist_with_first_frame:
                min_hamming_dist_with_first_frame = hamming_dist_with_first_frame
                closest_frame_index_first = frame_index
                closest_frame_timestamp_first = timestamp

            if hamming_dist_with_last_frame < min_hamming_dist_with_last_frame:
                min_hamming_dist_with_last_frame = hamming_dist_with_last_frame
                closest_frame_index_last = frame_index
                closest_frame_timestamp_last = timestamp

            frame_index += 1
        else:
            print('processed {} frames'.format(frame_index+1))
            break

    cap_original_video.release()
    print('timestamp_start={}, timestamp_end={}'.format(closest_frame_timestamp_first, closest_frame_timestamp_last))


if __name__ == '__main__':
    main()

关于python - 如何定位视频子集的时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62052409/

相关文章:

ios - iOS 上 mediaRecorder 的替代品

Python:将类对象转换为 JSON - 对象不可 JSON 序列化

python - 从每个文本行中获取一个子字符串

带有 Gstreamer 管道的 Python

c++ - 将 YCrCb 图像拆分为其强度 channel

javascript - video.js,在IE10上播放视频,但没有声音

java - 安卓 : Share intent is not working for video file path

python - 如何用空格填写 Python 字符串?

python - 如何根据 Numpy 中另一个数组的分组值生成数组?

java - OpenCV/JavaCV 人脸识别 - 非常相似的置信度值