I am reading an rtsp(local rtsp link) stream from my cctv camera connected on LAN.
My Main Goal :-
I want to perform some processing on the frames and want to display via m3u8 in real time or nearly real time so that i can display in the frontend using hls.js.
Currently i am trying to create video in realtime so that using ffmpeg i can create the m3u8 .
Sharing my code below.
import cv2
from moviepy.editor import *
import numpy as np
import time
url = "rtsp://username:password#192.168.1.100:10554/Streaming/channels/401"
cap = cv2.VideoCapture(url)
def make_video_file(clips):
try:
print(f"clips = {clips}")
video_clip = concatenate_videoclips(clips,method='compose')
video_clip.write_videofile("video-output.mp4",fps=30)
except Exception as e:
print(e)
FRAME_COUNTER = 0
NUMBER_OF_FRAMES = 30
CLIPS = [0 for i in range(NUMBER_OF_FRAMES)]
while True:
ret, frame = cap.read()
# print(frame)
if not ret:
continue
CLIPS.pop(0)
CLIPS.append(ImageClip(frame).set_duration(1))
if FRAME_COUNTER == NUMBER_OF_FRAMES:
try:
FRAME_COUNTER = 0
make_video_file(CLIPS)
except:
pass
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
NUMBER_OF_FRAMES += 1
cap.release()
cv2.destroyAllWindows()
Related
I'm using the below code to capture images from webcam. But i need only some no.of images to be captured on click.
# Opens the inbuilt camera of laptop to capture video.
cap = cv2.VideoCapture(0)
i = 0
while(cap.isOpened()):
ret, frame = cap.read()
# This condition prevents from infinite looping
# incase video ends.
if ret == False:
break
# Save Frame by Frame into disk using imwrite method
cv2.imwrite('Frame'+str(i)+'.jpg', frame)
i += 1
cap.release()
cv2.destroyAllWindows()```
Assuming you want 500 images add this:
...
i+=1
if (i+1)%500==0:
break
that would be easy. you can use k = cv2.waitKey(1) and check what button was pressed. here is a simple example:
import cv2
def main():
cap = cv2.VideoCapture(0)
if not cap.isOpened(): # Check if the web cam is opened correctly
print("failed to open cam")
return -1
else:
print('webcam open')
for i in range(10 ** 10):
success, cv_frame = cap.read()
if not success:
print('failed to capture frame on iter {}'.format(i))
break
cv2.imshow('click t to save image and q to finish', cv_frame)
k = cv2.waitKey(1)
if k == ord('q'):
print('q was pressed - finishing...')
break
elif k == ord('t'):
print('t was pressed - saving image {}...'.format(i))
image_path = 'Frame_{}.jpg'.format(i) # i recommend a folder and not to save locally to avoid the mess
cv2.imwrite(image_path, cv_frame)
cap.release()
cv2.destroyAllWindows()
return
if __name__ == '__main__':
main()
I'm trying to run a visual behaviour experiment where a whole heap of videos in a folder play one after another. I need to do this in python because I have a TTL pulse generator which I need to run at the start and end of each video.
I'm using cv2 and to try and play the videos but for reasons I can't figure out, I can't get them to play sequentially
Attached is my code
import cv2
import os
import random
videofolderPath = '/folderwithfiles'
videos = []
playlist = []
for file in os.listdir(videofolderPath):
if file.lower().endswith(".mp4"):
path=os.path.join('/folderwithfiles/',file)
playlist.append(path)
random.shuffle(playlist)
for i in range (3):
i += 1
cap = cv2.VideoCapture(playlist[i])
print(playlist[i])
while(True):
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q') or ret==False :
cap.release()
cv2.destroyAllWindows()
break
cv2.imshow('frame',frame)
cap.release()
cv2.destroyAllWindows()
The issue I'm having is I think they're all playing at once. When I press q I do see another video behind it but am struggling to get them to play one after another.
It looks like you have an error because you try to show the video before testing if ret == False.
Also, you should update i at the end of the loop as python indexing is zero based
The fix would look like this: (note that I changed the video folder path to test your code)
import cv2
import os
import random
videofolderPath = './videos'
videos = []
playlist = []
for file in os.listdir(videofolderPath):
if file.lower().endswith(".mp4"):
path = os.path.join(videofolderPath, file)
playlist.append(path)
random.shuffle(playlist)
for i in range(3):
cap = cv2.VideoCapture(playlist[i])
print(playlist[i])
while True:
ret, frame = cap.read()
# REMOVE cv2.imshow(f'frame_{i}', frame)
if cv2.waitKey(1) & 0xFF == ord('q') or ret == False:
cap.release()
cv2.destroyAllWindows()
break
cv2.imshow('frame', frame)
cap.release()
cv2.destroyAllWindows()
i += 1 # UPDATE INDEX AT THE END
A better way of writing your code would be something like this:
import cv2
import os
if __name__ == '__main__':
video_folder = "./videos"
for video_name in os.listdir(video_folder):
if not video_name.endswith(".mp4"):
continue
video_path = os.path.join(video_folder, video_name)
video = cv2.VideoCapture(video_path)
while True:
ret, frame = video.read()
if not ret:
break
cv2.imshow("video", frame)
cv2.waitKey(1)
video.release()
cv2.destroyAllWindows()
Also, I would recommend you to look at threading to load your video in "parallel" as it is very cpu intensive
I tried to write a small Python program which would allow me to start the webcam and capture and save the image to a .png file:
import cv2
cap = cv2.VideoCapture(0)
for i in range(3):
ret, frame = cap.read()
cap.release()
if ret == True:
cv2.imwrite(str(i) + 'image.png', frame)
else:
print("Webcam not working")
print(ret)
but when I execute it it would only save the image once under 0image.png and then display this in the console:
Webcam not working
False
Webcam not working
False
What am I doing wrong?
The cap.release() functions helps you to free up your system , i.e. , the camera device resource, and if not done so , then it will raise errors like Device or resource busy if you try to create a new instance .
So , you need to remove the cap.release() from your loop and place it at the end of your program .
This should work .
import cv2
cap = cv2.VideoCapture(0)
for i in range(3):
ret, frame = cap.read()
if ret == True:
cv2.imwrite(str(i) + 'image.png', frame)
else:
print("Webcam not working")
print(ret)`
cap.release()
am looking devolop something simply with opencv.Am looking to play videos from the web using opencv the way you can play videos from your laptop by passing the location path now a trying to pass the video url and get it to play.so far am getting error any suggestion would be nice.
import cv2
import numpy as np
import urllib3
http = urllib3.PoolManager()
r = http.request('Get','https://www.youtube.com/watch?v=NWdrO4BoCu8&list=RDNWdrO4BoCu8&start_radio=1')
cap = cv2.VideoCapture('https://www.youtube.com/watch?v=NWdrO4BoCu8&list=RDNWdrO4BoCu8&start_radio=1')
if (cap.isOpened()== False):
print("Error opening video file")
while(cap.isOpened()):
ret, frame = cap.read()
if ret == True:
cv2.imshow('Frame', frame)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()
Here you can use pafy to download the video, then use OpenCV to play the video.
url = 'https://youtu.be/W1yKqFZ34y4'
vPafy = pafy.new(url)
play = vPafy.getbest(preftype="webm")
#start the video
cap = cv2.VideoCapture(play.url)
while (True):
ret,frame = cap.read()
"""
your code here
"""
cv2.imshow('frame',frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
resources for installation:
https://pypi.org/project/pafy/
I have a RaspberryPi, a few IP camera's and I would like to get a fresh image from all these camera's every 5 minutes. I have the following script, which open the RTSP feed af grabs images ALL THE TIME, talking 10-25 every second it runs.
Is there a way to open the videofeed an take only 1 image?
import cv2
import time
cap = cv2.VideoCapture('rtsp://192.168.86.81:554/11') # it can be rtsp or http $
ret, frame = cap.read()
while ret:
cv2.imwrite('images/{}.jpg'.format(time.time()), frame)
ret, frame = cap.read()
This solved my problem. I removed time as I do not need this. I will let the aboce code stand in case anybody would want to play around with this
import cv2
cap = cv2.VideoCapture('rtsp://192.168.86.81:554/11') # it can be rtsp or http stream
ret, frame = cap.read()
if cap.isOpened():
_,frame = cap.read()
cap.release() #releasing camera immediately after capturing picture
if _ and frame is not None:
cv2.imwrite('images/latest.jpg', frame)
import cv2
import time
from datetime import datetime
import getpass
#imagesFolder = "C:/Users/<user>/documents"
# https://stackoverflow.com/questions/842059/is-there-a-portable-way-to-get-the-current-username-in-python
imagesFolder = "C:/Users/" + getpass.getuser() + "/documents"
#cap = cv2.VideoCapture("rtsp://192.168.86.81:554/11")
# Use public RTSP Streaming for testing, but I am getting black frames!
cap = cv2.VideoCapture("rtsp://192.168.86.81:554/11")
frameRate = cap.get(5) #frame rate
count = 0
while cap.isOpened():
start_time = time.time()
frameId = cap.get(1) # current frame number
ret, frame = cap.read()
if (ret != True):
break
filename = imagesFolder + "/image_" + str(datetime.now().strftime("%d-%m-%Y_%I-%M-%S_%p")) + ".jpg"
cv2.imwrite(filename, frame)
# Show frame for testing
cv2.imshow('frame', frame)
cv2.waitKey(1)
count += 1
#Break loop after 5*60 minus
if count > 5*60:
break
elapsed_time = time.time() - start_time
# Wait for 60 seconds (subtract elapsed_time in order to be accurate).
time.sleep(60 - elapsed_time)
cap.release()
print ("Done!")
cv2.destroyAllWindows()