3

I have a working python script that uses the video writer from opencv.

source https://gist.github.com/stanchiang/b4e4890160a054a9c1d65f9152172600


If i take in a file, and regardless of whether I simply pass the video frame through to the writer (effectively duplicating the file) or if i try to edit the frame, the file is always larger. I would like for it to be no larger than the original (since if you read my script i'm blurring a lot of stuff).

After checking their metadata, with ffprobe -v quiet -print_format json -show_format -show_streams inputFile.mp4 I notice that the bitrate of the new file is over 5.5x higher than before.

source https://www.diffchecker.com/8r2syeln


since bitrate is a big determinant of file size, I'm wondering if

  1. i can hardcode the desired bitrate of the new file through the video writer
  2. whether for some reason the heavily increased bit rate is needed
stanley
  • 1,021
  • 10
  • 25
  • You may want to switch to FFmpeg, as control of all video parameters is excellent there, and from my experience, the bitrate of the output won't be changed from the input. – boardrider Aug 01 '16 at 12:22
  • Can't switch all the way over right? The script edits the video frame by frame using an opencv algorithm. Is there a way I can use ffmpeg to write to a new video frame by frame? – stanley Aug 01 '16 at 16:09
  • @stanley No. The only way with your method is to completely write the video using OpenCV by generating all of the frames, then when you're done you use FFMPEG to compress the video by altering the bitrate. However, it's possible to directly send RGB data to FFMPEG using pipes but that does not use OpenCV. – rayryeng Aug 02 '16 at 02:34
  • @rayryeng if I can send rgb data to ffmpeg, then might there be a way to turn my opencv edited frame into rgb data to be used by ffmpeg? How would that code look? – stanley Aug 02 '16 at 02:51
  • Try this post. http://stackoverflow.com/q/32477586/3250829. – rayryeng Aug 02 '16 at 02:54
  • Thanks for the lead! – stanley Aug 02 '16 at 02:57
  • No problem. Remember to read the comment in the comment stream about the mistake you need to correct to make the code work. The nice thing about that post is that it writes numpy arrays to the ffmpeg pipe. OpenCV images are contained within numpy arrays so it will require very little work given that post. All in all, I would avoid using OpenCV VideoWriter if you want to make videos. For ones with a small amount of frames, sure no problem but not for larger ones. Let me know how it goes! – rayryeng Aug 02 '16 at 03:07
  • If it does work, I'd love to write an answer to help the community for the future. – rayryeng Aug 02 '16 at 03:11
  • 1
    Also try this one too: http://stackoverflow.com/q/13294919/3250829 – rayryeng Aug 02 '16 at 04:33

1 Answers1

3

basically this answer https://stackoverflow.com/a/13298538/1079379

# import packages
from PIL import Image
from subprocess import Popen, PIPE
from imutils.video import VideoStream
from imutils.object_detection import non_max_suppression
from imutils import paths
import cv2
import numpy as np
import imutils

# ffmpeg setup
p = Popen(['ffmpeg', '-y', '-f', 'image2pipe', '-vcodec', 'mjpeg', '-r', '24', '-i', '-', '-vcodec', 'h264', '-qscale', '5', '-r', '24', 'video.mp4'], stdin=PIPE)

video = cv2.VideoCapture('videos.mp4')

while True:
    ret, frame = video.read()
    if ret:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        im = Image.fromarray(frame)
        im.save(p.stdin, 'JPEG')
    else:
        break

p.stdin.close()
p.wait()
video.release()
cv2.destroyAllWindows()
Community
  • 1
  • 1
stanley
  • 1,021
  • 10
  • 25