FFMPEG-本地视频到UDP流到OpenCV-视频质量下降

时间:2020-04-26 10:56:28

标签: python opencv ffmpeg video-streaming http-live-streaming

我的目标是将本地视频内容/桌面屏幕广播重新流化为我需要在Python脚本上处理的UDP流。

这是我正在使用的FFMPEG脚本:

interface GenericTrait {
    val isDisabled: Boolean
}

class TraitImpl : GenericTrait {
    override val isDisabled = Random.nextBoolean()
}

// define methods out of class declaration
fun <T: Any> GenericTrait.method(value: T) {
    println("Type of value is ${value::class}, and the value is $value. I am $isDisabled")
}

这是应该读取流流的简单Python脚本:

ffmpeg -re -i C:\Users\test\Downloads\out.ts -strict -2 -c:v copy -an -preset slower -tune stillimage -b 11200k -f rawvideo udp://127.0.0.1:5000

我能够按预期可视化流视频的一部分,但是我面临着视频质量下降的许多问题,特别是可能由于缺少数据包处理而导致的视频伪像:

enter image description here

这些也是我从脚本获得的错误日志:

import cv2

cap = cv2.VideoCapture('udp://127.0.0.1:5000',cv2.CAP_FFMPEG)
if not cap.isOpened():
    print('VideoCapture not opened')
    exit(-1)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)  # float
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)  # float
print(str(width))
print(str(height))
while True:
    ret, frame = cap.read()
    imgray = frame[int(round((height/100)*70,0)):int(round((width/100)*42,0)), int(round((height/100)*74,0)):int(round((width/100)*54,0))]
    if not ret:
        print('frame empty')
        break
    cv2.imshow('image', imgray)
    if cv2.waitKey(1)&0XFF == ord('q'):
        break
cap.release()

实际上我并不关心视频的流动性,我还可以降低FPS,重要的是视频质量。不知道我在脚本python部分上做错了还是我在使用错误的FFMPEG命令。

非常感谢

1 个答案:

答案 0 :(得分:0)

对于视频质量,您将必须使用多线程。它会修复它。我会给你一个可以工作的例子。

import threading
import queue

q = queue.Queue()

def recieve():
    cap = cv2.VideoCapture('udp://@127.0.0.1:5000?buffer_size=65535&pkt_size=65535&fifo_size=65535')        
    ret, frame = cap.read()
    q.put(frame)
    while ret:
        ret, frame = cap.read()
        q.put(frame)


def display():
    while True:
        if q.empty() != True:
            frame = q.get()                
            cv2.imshow('Video', frame)

        k = cv2.waitKey(30) & 0xff
        if k == 27:  # press 'ESC' to quit
            break

p1 = threading.Thread(target=recieve).start()
p2 = threading.Thread(target=display).start()
相关问题