257 lines
7.8 KiB
Python
Executable File
257 lines
7.8 KiB
Python
Executable File
# -*- 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() |