# -*- coding: utf-8 -*- ######################################## # HXbot camera control module # # EoF 2016 EoF@itphx.ru # ######################################## import subprocess import threading #import select import time import sys import os.path as path import HX class HXcamClass(): def __init__(self): super(HXcamClass, self).__init__() self.__e = None self.__t = None self.mcam = None self.rcam = None self.mmic = None self.rvid = None self.is_running = False # Subprocess states # 0 - Not running # 1 - Running # 2 - Error # 3 - Device not found self.mcam_state = HX.CAM_STATE_STP self.rvid_state = HX.CAM_STATE_STP self.rcam_state = HX.CAM_STATE_STP self.mmic_state = HX.CAM_STATE_STP self.mcam_wrn_count = 0 self.rcam_wrn_count = 0 self.mmic_wrn_count = 0 def start(self): self.__e = threading.Event() self.__t = threading.Thread(target=self.__process, args=(self.__e, )) self.mcam_start() #self.rcam_start() self.mmic_start() self.__t.start() self.is_running = True def stop(self): self.__e.set() self.__t.join() self.__e = None self.__t = None self.mcam_stop() #self.rcam_stop() self.mmic_stop() self.is_running = False def restart(self): if self.is_running: self.__stop() self.__start() def test(self): #import time #import sys #import shlex #string = "" #args = shlex.split(string) #print(args) #sys.exit() pass def mcam_start(self): # cvlc 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15' # --sout '#rtp{sdp=rtsp://:8554/video}' -v --live-caching 50 if path.exists('/dev/video0'): arg = 'v4l2:///dev/video0:chroma=H264:width=1280:height=720:fps=15' elif path.exists('/dev/video1'): arg = 'v4l2:///dev/video1:chroma=H264:width=1280:height=720:fps=15' else: self.mcam_state = HX.CAM_STATE_ERR return self.mcam = subprocess.Popen( args=['/usr/bin/cvlc', arg, '--sout', '#rtp{sdp=rtsp://:8554/video}', '--live-caching', '50', 'vlc://quit'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.mcam_state = HX.CAM_STATE_RUN def mcam_stop(self): if self.mcam_state != HX.CAM_STATE_ERR: self.mcam.terminate() self.mcam_state = HX.CAM_STATE_STP def rcam_start(self): # raspivid -t 0 -n -w 1280 -h 720 -fps 15 -o - | # cvlc -v stream:///dev/stdin # --sout '#rtp{sdp=rtsp://:8555/video}' :demux=h264 self.rvid = subprocess.Popen( args=['raspivid', '-t', '0', '-n', '-w', '1280', '-h', '720', '-fps', '15', '-o', '-'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) self.rcam = subprocess.Popen( args=['cvlc', 'stream:///dev/stdin', '--sout', '#rtp{sdp=rtsp://:8555/video}', ':demux=h264', '--live-caching', '50', 'vlc://quit'], stdin=self.rvid.stdout, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.rcam_state = HX.CAM_STATE_RUN def rcam_stop(self): if self.rcam_state != HX.CAM_STATE_ERR: self.rvid.terminate() self.rcam.terminate() self.rcam_state = HX.CAM_STATE_STP def mmic_start(self): # cvlc -v 'alsa://hw:1,0' # --sout '#transcode{acodec=mpga,ab=128,channels=2,samplerate=44100} # :rtp{sdp=rtsp://:8556/audio}' self.mmic = subprocess.Popen( args=['cvlc', 'alsa://hw:0,0', '--sout', '#transcode{acodec=mpga,ab=128,channels=2,samplerate=44100}' + ':rtp{sdp=rtsp://:8556/audio}', '--live-caching', '500', 'vlc://quit'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) self.mmic_state = HX.CAM_STATE_RUN def mmic_stop(self): if self.mmic_state != HX.CAM_STATE_ERR: self.mmic.terminate() self.mmic_state = HX.CAM_STATE_STP def __process(self, stopRequest): # Process loop while not stopRequest.is_set(): # Main Camera if self.mcam_state != HX.CAM_STATE_ERR: if self.mcam.poll() is not None: self.mcam_start() if self.mcam_state != HX.CAM_STATE_WRN: self.mcam_wrn_count += 1 if self.mcam_wrn_count >= HX.CAM_MAX_WRN_COUNT: self.mcam_state = HX.CAM_STATE_WRN # Rear Camera #if self.rcam_state != HX.CAM_STATE_ERR: #if self.rcam.poll() is not None: #self.rcam_start() #if self.rcam_state != HX.CAM_STATE_WRN: #self.rcam_wrn_count += 1 #if self.rcam_wrn_count >= HX.CAM_MAX_WRN_COUNT: #self.rcam_state = HX.CAM_STATE_WRN # Main Microphone if self.mmic_state != HX.CAM_STATE_ERR: if self.mmic.poll() is not None: self.mmic_start() if self.mmic_state != HX.CAM_STATE_WRN: self.mmic_wrn_count += 1 if self.mmic_wrn_count >= HX.CAM_MAX_WRN_COUNT: self.mmic_state = HX.CAM_STATE_WRN time.sleep(HX.CAM_DELAY) #if self.mcam_state == 1: ## VLC-1 #r, w, e = select.select([self.mcam.stderr], [], [], 0.5) #if self.mcam.stderr in r: #print("VLC-1 ERROR:") #print(self.mcam.stderr.readline()) #r, w, e = select.select([self.mcam.stdout], [], [], 0.5) #if self.mcam.stdout in r: #print("VLC-1 OUT:") #print(self.mcam.stdout.readline()) #if self.rvid_state == 1: ## VLC-2 #r, w, e = select.select([self.rvid.stderr], [], [], 0.5) #if self.rvid.stderr in r: #print("RVID ERROR:") #print(self.rvid.stderr.readline()) #r, w, e = select.select([self.rcam.stderr], [], [], 0.5) #if self.rcam.stderr in r: #print("VLC-2 ERROR:") #print(self.rcam.stderr.readline()) #r, w, e = select.select([self.rcam.stdout], [], [], 0.5) #if self.rcam.stdout in r: #print("VLC-2 OUT:") #print(self.rcam.stdout.readline()) #if self.mmic_state == 1: ## VLC-3 #r, w, e = select.select([self.mmic.stderr], [], [], 0) #if self.mmic.stderr in r: #print("MMIC ERROR:") #print(self.mmic.stderr.readline()) #r, w, e = select.select([self.mmic.stdout], [], [], 0.5) #if self.mmic.stdout in r: #print("MMIC OUT:") #print(self.mmic.stdout.readline()) def main(): HXcam = HXcamClass() HXcam.start() print("Execution started") command_view = '"Return" or CTRL+C to exit>' try: while True: command = input(command_view) if command == "": HXcam.stop() sys.exit() except KeyboardInterrupt: print("Terminate...") HXcam.stop() if __name__ == '__main__': main()