I would like to know how I could go about playing audio from a specific position in a video file, using ffpyplayer.
I know how to set the frame I want to start playing at in opencv but not in ffplayer.
Any ideas or suggestions would help a ton. Here is what I have came up with.
import cv2
from ffpyplayer.player import MediaPlayer
video_path=videoName
def PlayVideo(video_path):
font = cv2.FONT_HERSHEY_SIMPLEX
video = cv2.VideoCapture(video_path)
video.set(cv2.CAP_PROP_POS_FRAMES, 7200)
player = MediaPlayer(video_path)
while True:
grabbed, frame = video.read()
audio_frame, val = player.get_frame()
if not grabbed:
print("End of video")
break
if cv2.waitKey(28) & 0xFF == ord("q"):
break
cv2.imshow("Video", frame)
if val != 'eof' and audio_frame is not None:
#audio
img, t = audio_frame
video.release()
cv2.destroyAllWindows()
PlayVideo(video_path)
Related
I want to run some mp4 videos inside a process but only camera feed works. The software gets stuck with no error message. I already tried both and I found this doesn't run. The print is where the code gets stuck.
import cv2
import multiprocessing
dispW=640
dispH=480
# Camera inputs
cap=cv2.VideoCapture('/home/kc/Downloads/darknet/1.mp4')
cap.set(cv2.CAP_PROP_FRAME_WIDTH, dispW)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, dispH)
#cv2.namedWindow("Window")
def c1():
global cap
while True:
print('here')
success, img = cap.read()
#ret, frame1 = cap1.read()
#frame2 = numpy.hstack((frame,frame1))
print('here')
cv2.imshow("Window2", img)
#This breaks on 'q' key
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
tCap1 = multiprocessing.Process(target=c1)
tCap1.start()
this runs.
import cv2
import multiprocessing
dispW=640
dispH=480
# Camera inputs
cap=cv2.VideoCapture('/dev/video0')
cap.set(cv2.CAP_PROP_FRAME_WIDTH, dispW)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, dispH)
#cv2.namedWindow("Window")
def c1():
global cap
while True:
success, img = cap.read()
#ret, frame1 = cap1.read()
#frame2 = numpy.hstack((frame,frame1))
print('here')
cv2.imshow("Window2", img)
#This breaks on 'q' key
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
tCap1 = multiprocessing.Process(target=c1)
tCap1.start()
I need an example of mp4 file run in a multiprocessing way.
Here's a minimal working example with optional FPS control. If you need to extract frames from your process back to the main program, you can use multiprocessing.Queue() to transfer frames since multiprocesses have an independent memory stack.
import multiprocessing as mp
import cv2, time
def capture_frames():
src = 'test.mp4'
capture = cv2.VideoCapture(src)
capture.set(cv2.CAP_PROP_BUFFERSIZE, 2)
# FPS = 1/X, X = desired FPS
FPS = 1/120
FPS_MS = int(FPS * 1000)
while True:
# Ensure camera is connected
if capture.isOpened():
(status, frame) = capture.read()
# Ensure valid frame
if status:
cv2.imshow('frame', frame)
else:
break
if cv2.waitKey(1) & 0xFF == ord('q'):
break
time.sleep(FPS)
capture.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
print('Starting video stream')
capture_process = mp.Process(target=capture_frames, args=())
capture_process.start()
Related camera/IP/RTSP/streaming, FPS, video, threading, and multiprocessing posts
Python OpenCV streaming from camera - multithreading, timestamps
Video Streaming from IP Camera in Python Using OpenCV cv2.VideoCapture
How to capture multiple camera streams with OpenCV?
OpenCV real time streaming video capture is slow. How to drop frames or get synced with real time?
Storing RTSP stream as video file with OpenCV VideoWriter
OpenCV video saving
Python OpenCV multiprocessing cv2.VideoCapture mp4
I want to write a video using OpenCv and process every frames in different seconds.
I am using cv2.VideoWriter, but the output file shows only the first frame of my video and it is not playing. I wanted to add text on the first frame and it did it, but it doesn't continue with the rest of the video.
As you can see from the code below, it creates a new output file for the new processed video.
It does create the mp4 file, but only showing first frame with the added text and it is not playing.
Any suggestion why this is happening?
Here is my code, I am using Spyder and windows.
fps = int(round(cap.get(5)))
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_video_file,fourcc,fps,(frame_width,frame_height))
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
if ret:
if cv2.waitKey(28) & 0xFF == ord('q'):
break
if between(cap, 0, 10000):
font = cv2.FONT_HERSHEY_COMPLEX_SMALL
cv2.putText(frame,'hello',org=(10,600),fontFace=font,fontScale=10,color=(255,0,0),thickness=4)
pass
# Our operations on the frame come here
out.write(frame)
# Display the resulting frame
cv2.imshow('frame',frame)
Exactly I could not find the problem in your code because you did not give the between function. However you may try following snippet:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
if (cap.isOpened() == False):
print("Unable to read camera feed")
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
fps = int(round(cap.get(5)))
out = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_width, frame_height))
while (True):
ret, frame = cap.read()
if ret == True:
cv2.putText(frame, 'hello',
org=(10, 300),
fontFace=cv2.FONT_HERSHEY_SIMPLEX,
fontScale=5,
color=(255, 0, 0),
thickness=4)
out.write(frame)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
so I found this code somewhere and I tried running it:
import cv2
from ffpyplayer.player import MediaPlayer
video_path = "video.mp4"
def video_audio(path):
video = cv2.VideoCapture(video_path)
player = MediaPlayer(video_path)
while True:
ret, frame = video.read()
audio_frame, val = player.get_frame()
if not ret:
print("End of video")
break
if cv2.waitKey(28) & 0xFF == ord("q"):
break
cv2.imshow("Video", frame)
if val != 'eof' and audio_frame is not None:
# audio
img, t = audio_frame
video.release()
cv2.destroyAllWindows()
video_audio(video_path)
it does actually play the video and audio, but there is a delay between the two (current audio frame is played ahead of the current video frame)
does anyone know a possible solution to fix that?
I'm stuck at audio..
Is there any easy way to put that two together?
Do I have to sync them both or can I somehow just extract audio to the existing code? :/
I'm new in python :P
My code:
import cv2
import numpy as np
file_name = "path to video"
window_name = "window"
interframe_wait_ms = 30
cap = cv2.VideoCapture(file_name)
if not cap.isOpened():
exit()
cv2.namedWindow(window_name, cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
while (True):
ret, frame = cap.read()
if ret:
cv2.imshow(window_name, frame)
else:
cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
if cv2.waitKey(interframe_wait_ms) & 0x7F == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Nevermind, i resolved this using ffpyplayer, but i still have problems when video reloads, music is bugged
I am new to both OpenCV and Python, and I am trying to create a simple program that will read in a video file named 'SixtyFPS.mov' and replay the video when it has reached its end. Ideally I would like to have the video loop continuously. I have not been able to find a solution for this online, however most of the answers I see involve using cap.set(cv2.CAP_PROP_POS_FRAMES, 1) or something of that nature in order to reset the frames. If anyone can explain to me how to use the cap.set feature in order to restart the video that would be greatly appreciated.
# The video 'SixtyFPS.mov' was recorded on an iPhone 7 at 60 FPS
# The video has a length of roughly 4 seconds long and so the total number
# of frames should be ~240, however my number_of_frames variable is equal to 115
# I am looking for a way to restart the video once it has reached its end but
# I have not yet discovered a good method for doing so. Any advice would be
# greatly appreciated. I am using Python 3.6.4 and OpenCV 3.3.1
# I needed to rotate the video so that it would be viewed in portrait
# orientation rather than landscape
import cv2
import numpy as np
# Load in the video
video_cap = cv2.VideoCapture('SixtyFPS.mov')
# display the total number of frames. Should be ~240 and not 115
number_of_frames = int(video_cap.get(cv2.CAP_PROP_FRAME_COUNT))
print("The total number of frames is: " + str(number_of_frames))
# Check if video opened successfully
if (video_cap.isOpened() == False):
print("Error opening video file")
frame_counter = 0
# Read until video is completed
while(video_cap.isOpened()):
# Capture frame-by-frame
ret, frame = video_cap.read()
if ret == True:
frame_counter += 1
# resize the window
resized_vid = cv2.resize(frame, (720, 1280))
# Convert the video to grayscale
grayscale_vid = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Change the orientation from landscape to portrait by rotating
(h, w) = grayscale_vid.shape[:2]
center = (w / 2, h / 2)
M = cv2.getRotationMatrix2D(center, 270, 1.0)
rotated_video = cv2.warpAffine(grayscale_vid, M, (w, h))
# Display the rotated video
cv2.imshow('Pitch', rotated_video)
# trying to restart the video when the frame_counter
# reaches its maximum value of 110
if frame_counter >= 110:
# here is where I think I need to restart the video
# by setting the current frame to zero
# Press Q on keyboard to exit
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Break the loop
else:
break
# When everything done, release the video capture object
video_cap.release()
# Closes all the frames
cv2.destroyAllWindows()
It's been a while since this question has been posted, but just in case someone stumbled upon this answer, this code snippet with cap.set() worked for me. I relied on the documentation that can be found here (cpp) and here (python).
import cv2
# Get video handle.
cap = cv2.VideoCapture("path/to/video")
if not cap.isOpened():
print("Cannot initialize cap.")
exit()
# Get length of the video.
video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# Initialize count.
count = 0
# Frames loop.
while True:
# Check length of the video.
if count == video_length:
# Reset to the first frame. Returns bool.
_ = cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
count = 0
# Get the frame.
success, image = cap.read()
if not success:
print("Cannot read frame.")
break
# do something with the image.
cv2.imshow("Frame", image)
# Quit by pressing 'q'.
if cv2.waitKey(1) & 0xFF == ord('q'):
break
count += 1
# Post loop.
cap.release()
cv2.destroyAllWindows()
I used the above to go some n number of frames back by combining cap.get() and cap.set().
This is a general way how the video can be resized to 480 x 800 (height x width) and made to loop.
import cv2
# Change this path to your video location
path = "path_to_your_video"
cap = cv2.VideoCapture(path)
while True:
ret, img = cap.read()
if not ret:
cap = cv2.VideoCapture(path)
ret, img = cap.read()
img = cv2.resize(img, (800, 480))
cv2.imshow("Video", img)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()