の続きで、ONVIFのメソッドを使って、カメラのIPアドレスから、RTSP StreamのURIを取ってきて、表示するPlayerを作りました。
ここでは、rtspライブラリを使っていますが、このライブラリは、OpenCVに依存していて、OpenCVが、RTSP Video Streamを開いて、OpenCVのVideoCaptureで取得したイメージを、PILのImageに変換しています。
その後、PillowのImageTKで、TKInterで表示できる画像に変換し、表示しています。
import tkinter as tk
from PIL import Image, ImageTk
import threading
import rtsp
from onvif import ONVIFCamera
import os
SCRIPTDIR = os.path.dirname(os.path.realpath(__file__))
class MainWindow:
def __init__(self, window, rtsp_url):
self.window = window
self.window.geometry('800x500')
self.window.title('ONVIF Player')
self.rtsp_url = rtsp_url
self.interval = 1 # Interval in ms to get the latest frame
self.client = rtsp.Client(rtsp_server_uri=rtsp_url, verbose=True)
self.window.protocol("WM_DELETE_WINDOW", self.on_closing_window)
# Create canvas for image
self.canvas = tk.Canvas(self.window, width=800, height=500)
self.canvas.grid(row=0, column=0)
self.canvas.create_rectangle(0, 0, 800, 500, fill="black")
self.rtsp_image = None
# Update image on canvas
self.update_image()
def on_closing_window(self):
self.client.close()
self.window.destroy()
def update_image(self):
# Get the latest frame and convert image format
frame = self.client.read()
if frame is not None:
# Update image on canvas
self.rtsp_image = ImageTk.PhotoImage(frame)
self.canvas.create_image(0, 0, image=self.rtsp_image, anchor=tk.NW)
# Repeat every 'interval' ms
self.window.after(self.interval, self.update_image)
if __name__ == "__main__":
# To avoid 'No such file: devicemgmt.wsdl', copied wsdl folder from
# https://github.com/FalkTannhaeuser/python-onvif-zeep/tree/zeep/wsdl
mycam = ONVIFCamera('192.168.1.18', 8000, 'admin', 'admin', os.path.join(SCRIPTDIR, 'wsdl'))
media_service = mycam.create_media_service()
profile_token = mycam.media.GetProfiles()[0].token
get_stream_uri = media_service.create_type("GetStreamUri")
get_stream_uri.ProfileToken = profile_token
get_stream_uri.StreamSetup = {'Stream': 'RTP-Unicast', 'Transport': {'Protocol': 'RTSP'}}
stream_uri = media_service.GetStreamUri(get_stream_uri)
rtsp_url = stream_uri.Uri
root = tk.Tk()
app = MainWindow(root, rtsp_url)
root.mainloop()