예제 #1
0
    def _connect(self, username, session):
        if self._thread is None:
            _logger.log('Octoprint Socket: Connecting')

            def _on_message(ws, message):
                # _logger.log('Octoprint socket message recieved: %s' % message)
                self._callback.on_event(event=message)

            def _on_error(ws, error):
                _logger.log('Octoprint Socket Error: %s' % error)

            def _on_close(ws):
                _logger.log('Octoprint Socket: Ws Closed')
                self._callback.disconnected()

            def _on_open(ws):
                _logger.log('Octoprint Socket: Ws Opened')
                self._ws.send(
                    _json.dumps({'auth': '%s:%s' % (username, session)}))
                self._ws.send(_json.dumps({'throttle': 10}))
                self._callback.connected()

            try:
                self._ws = websocket.WebSocketApp(
                    "ws://localhost:5000/sockjs/websocket",
                    on_message=_on_message,
                    on_error=_on_error,
                    on_close=_on_close,
                    on_open=_on_open)

                self._thread = threading.Thread(target=self._ws.run_forever)
                self._thread.daemon = True
                self._thread.start()
            except Exception as e:
                _logger.warn(e)
예제 #2
0
    def __init__(self, janus_url, port, machine, system, is_raspberry=False):
        self._url = "rtp://%s:%d?pkt_size=1300" % (janus_url, port)
        self._callback = None
        self._process = None
        self._vcodec = 'libx264' if not is_raspberry else 'h264_omx'
        self._shutting_down = False
        self._flip_horizontally = False
        self._flip_vertically = False
        self._rotate_90_clockwise = False
        self._enabled = False
        self._extra_arguments = {'s': '640x480', 'b:v': 500000}

        if system == 'Linux':
            if machine == 'armv7l':
                self._ffmpeg_dir = os.path.join(config.FFMPEG_DIR, 'linux',
                                                'armv7l', 'ffmpeg')
            else:
                self._ffmpeg_dir = os.path.join(config.FFMPEG_DIR, 'linux',
                                                'x86_64', 'ffmpeg')
                self._extra_arguments['preset'] = 'medium'
                self._extra_arguments['crf'] = 17
                self._extra_arguments['tune'] = 'zerolatency'
            self._enabled = True
            os.system("chmod -R 777 %s" % config.FFMPEG_DIR)
        else:
            self._ffmpeg_dir = None
            _logger.log('Unable to start ffmpeg on %s system' % system)
예제 #3
0
    def connect(self):
        if self._enabled:
            _logger.log('Janus: Connecting')

            def _on_error(ws, error):
                _logger.log('Janus Error: %s' % error)

            def _on_message(ws, msg):
                self._process_msg(msg)

            def _on_close(ws):
                _logger.log('Janus: Ws Closed')
                self._callback.disconnected()

            def _on_open(ws):
                _logger.log('Janus: Ws Opened')
                self._create_session()

            try:
                self._ws = websocket.WebSocketApp(
                    self._url,
                    on_open=_on_open,
                    on_message=_on_message,
                    on_close=_on_close,
                    on_error=_on_error,
                    subprotocols=['janus-protocol'])
                self._ws_thread = threading.Thread(target=self._ws.run_forever)
                self._ws_thread.daemon = True
                self._ws_thread.start()
            except Exception as e:
                _logger.warn(e)
예제 #4
0
    def __init__(self, machine, system, ports, callback=None):
        _logger.log('Janus Socket: Initializing')

        # websocket.enableTrace(True)
        self._janus_ws_port = ports[0]
        self._janus_api_port = ports[1]
        self._janus_video_port = ports[2]
        self._url = 'ws://%s:%d/' % (config.JANUS_HOST, self._janus_ws_port)
        self._janus_thread = None
        self._janus_proc = None
        self._ws = None
        self._ws_thread = None
        self._transaction = None
        self._session_id = None
        self._handle_id = None
        self._paused = False
        self._streams = []
        self._callback = callback
        self._stream_on_start = False
        self._enabled = False
        self._started_at = None

        if system == 'Linux':
            if machine == 'armv7l':
                self._janus_dir = os.path.join(config.JANUS_DIR, 'linux',
                                               'armv7l')
            else:
                self._janus_dir = os.path.join(config.JANUS_DIR, 'linux',
                                               'x86_64')
            self._enabled = True
            os.system("chmod -R 777 %s" % config.JANUS_DIR)
        else:
            self._janus_dir = None
            _logger.log('Unable to start janus on %s system' % system)
예제 #5
0
    def start(self,
              url=None,
              flip_horizontally=False,
              flip_vertically=False,
              rotate_90_clockwise=False):
        if self._enabled:
            if not self._process:
                self._flip_horizontally = flip_horizontally
                self._flip_vertically = flip_vertically
                self._rotate_90_clockwise = rotate_90_clockwise

                self._shutting_down = False
                url = url if url else 'http://localhost:8080/?action=stream'
                try:
                    _logger.log(url)
                    code = urlopen(url).getcode()
                except Exception:
                    code = 404

                if code == 200:
                    self._stream_from_url(url=url)
                else:
                    self._stream_from_device()

                self.monitor(self._process)
예제 #6
0
		def user_joined(data):
			_logger.log('Plabric Socket: User joined')
			if self._callback:
				data = _json.loads(data) if isinstance(data, str) else data
				user_nick = data['user_nick']
				octoprint_api_key = data['octoprint_api_key']
				self._callback.on_user_joined(user_nick, octoprint_api_key)
예제 #7
0
 def start_video_stream(self):
     _logger.log('Janus: Start video stream')
     if not self.ws_connected():
         self._stream_on_start = True
         self.connect()
     else:
         self._start_streams(self._streams[0])
예제 #8
0
    def on_startup(self, host, port):
        _logger.log('On Plabric Startup')
        self._host = host
        self._port = port
        self._main = Main(self)

        if self._main.plabric_api_key:
            self._main.start()
예제 #9
0
 def disconnect(self):
     self.set_loading(True)
     _logger.log('Disconnecting Plabric Plugin')
     self.video_streamer.stop()
     self.octoprint_socket.disconnect()
     self.plabric_socket.disconnect()
     self.plabric_webrtc.disconnect()
     self.set_step(Step.LOGIN_NEEDED)
     self.set_loading(False)
예제 #10
0
 def save_setting(self, key, value):
     s = self.get_saved_settings()
     _logger.log('Saved key: %s - %s' % (key, value))
     if s is None:
         s = {}
     s[key] = value
     config_path = self._plugin.get_plugin_data_folder() + "/.config.yaml"
     with open(config_path, 'w+') as outfile:
         yaml.dump(s, outfile, default_flow_style=False)
예제 #11
0
 def start_video_stream(self):
     _logger.log('Janus: Start video stream')
     if time.time() - self._started_at < 4:
         time.sleep(4)
     if not self.ws_connected():
         self._stream_on_start = True
         self.connect()
     else:
         self._start_streams(self._streams[0])
예제 #12
0
 def stop_video_stream(self):
     _logger.log('Janus: Stop video stream')
     if self.ws_connected():
         self._paused = True
         body = {'request': 'pause', 'id': self._streams[0]['id']}
         self._send_msg(body=body,
                        transaction='stop_stream_%d' %
                        self._streams[0]['id'])
         self._callback.video_stream_paused()
예제 #13
0
 def clear_setting(self, key):
     s = self.get_saved_settings()
     _logger.log('Clear key: %s' % key)
     if s is None:
         return
     if key in s:
         s.pop(key)
     config_path = self._plugin.get_plugin_data_folder() + "/.config.yaml"
     with open(config_path, 'w+') as outfile:
         yaml.dump(s, outfile, default_flow_style=False)
예제 #14
0
 def _attach_plugin(self):
     _logger.log('Janus: Attaching plugin')
     data = _json.dumps({
         'janus': 'attach',
         'transaction': 'attach_plugin',
         'session_id': self._session_id,
         'plugin': 'janus.plugin.streaming',
         'request': 'list'
     })
     self._send_to_janus(data)
예제 #15
0
	def connect(self):
		try:
			if not self._sio.connected and not self._connecting:
				self._connecting = True
				_logger.log('Plabric Socket: Connecting')
				self._sio.connect(self._domain, namespaces=[config.PLABRIC_SOCKET_NAMESPACE])
		except (socketio.exceptions.ConnectionError, ValueError) as e:
			_logger.warn(e)
			self._connecting = False
			self._callback.on_connection_error()
예제 #16
0
    def start(self, from_oauth=False):
        _logger.log('Starting')
        self.set_error('')
        if from_oauth and not self.plabric_api_key:
            f = self.probe_plugin_appkeys
        else:
            f = self.connect

        self._thread = threading.Thread(target=f)
        self._thread.daemon = True
        self._thread.start()
예제 #17
0
	def __init__(self, domain, callback):
		_logger.log('Plabric Socket: Initializing')
		self._domain = domain
		self._sio = socketio.Client(
			reconnection=False,
			logger=False,
		)
		self._add_event_handlers()
		self._callback = callback
		self._t = None
		self._connecting = False
예제 #18
0
 def on_answer_received(self, json):
     _logger.log('Janus: Answer received')
     jsep = {'type': 'answer', 'sdp': json['sdp']}
     data = _json.dumps({
         'janus': 'message',
         'transaction': 'on_answer_received',
         'session_id': self._session_id,
         'handle_id': self._handle_id,
         'body': {},
         'jsep': jsep
     })
     self._send_to_janus(data)
예제 #19
0
 def on_ice_candidate_received(self, json):
     _logger.log('Janus: Ice candidate received')
     candidate = {
         'sdpMid': json["id"],
         'sdpMlineIndex': json["label"],
         'candidate': json['candidate']
     }
     data = _json.dumps({
         'janus': 'trickle',
         'transaction': 'on_ice_candidate_received',
         'session_id': self._session_id,
         'handle_id': self._handle_id,
         'candidate': candidate
     })
     self._send_to_janus(data)
예제 #20
0
    def set_step(self, step):
        self.step = step
        self.plugin.update_ui_status()

        if step == Step.ERROR_CONNECTION and not self._waiting_for_reconnect:
            _logger.log('Retry connection in %d seconds' % self.retry_time)
            self._waiting_for_reconnect = True

            thread = threading.Thread(target=self.retry_in_seconds,
                                      args=(self.retry_time, ))
            thread.daemon = True
            thread.start()

        if step == Step.CONNECTED or step == Step.READY:
            self.retry_time = randrange(30, 120)
예제 #21
0
    def set_step(self, step):
        self.step = step
        self.plugin.update_ui_status()

        if step == Step.ERROR_CONNECTION and not self._waiting_for_reconnect and self._auto_reconnect:
            seconds = randrange(60, 300)
            _logger.log('Retry connection in %d seconds' % seconds)
            self._waiting_for_reconnect = True
            time.sleep(seconds)
            self._waiting_for_reconnect = False
            if self.step == Step.ERROR_CONNECTION:
                self.plabric_socket.disconnect()
                self.plabric_socket = None
                self._init_plabric_socket()
                self.connect()
예제 #22
0
    def upload_file(self, data, file_path, callback):
        _logger.log('Octoprint API: Uploading file')
        action = DataAction(raw=data)
        file_name = data['params']['file_name']
        _logger.log('%s Post file on: %s' %
                    (self._name, self._get_url(action.path)))

        files = {
            "file": ("%s.gcode" % file_name, open(file_path, "rb").read())
        }
        payload = {'path': 'plabric/tmp', 'select': 'true', 'print': 'false'}
        self._execute(
            requests.post(self._get_url(action.path),
                          data=payload,
                          files=files,
                          headers={'X-Api-Key': self._api_key}), callback)
예제 #23
0
 def execute_dowload(self, url, destination, callback):
     _logger.log('Plabric API: Downloading file')
     r = requests.get(url, stream=True)
     if r.status_code == 200:
         with open(destination, 'wb') as f:
             total_size = int(r.headers.get('content-length', 0))
             if total_size is None:
                 f.write(r.content)
             else:
                 dl = 0
                 for data in r.iter_content(chunk_size=4096):
                     dl += len(data)
                     f.write(data)
         callback.on_succeed(None)
     else:
         callback.on_error(r.status_code)
예제 #24
0
    def configure(self, json_servers):
        if not self._enabled:
            return
        _logger.log('Janus: Configuring')
        self._json_servers = json_servers

        stun_server = None
        stun_port = None

        turn_server = None
        turn_port = None
        turn_username = None
        turn_credential = None

        for s in json_servers:
            if 'username' in s and 'credential' in s:
                if not turn_server:
                    turn_server, turn_port = s['urls'][0].replace(
                        'turn:', '').split(":")
                    turn_username = s['username']
                    turn_credential = s['credential']
            else:
                if not stun_server:
                    stun_server, stun_port = s['urls'][0].replace(
                        'stun:', '').split(":")

        self._process_config_file(name='janus',
                                  params={
                                      'JANUS_DIR': self._janus_dir,
                                      'TURN_SERVER': turn_server,
                                      'TURN_PORT': turn_port,
                                      'TURN_USERNAME': turn_username,
                                      'TURN_CREDENTIAL': turn_credential,
                                      'STUN_SERVER': stun_server,
                                      'STUN_PORT': stun_port
                                  })
        self._process_config_file(
            name='janus.transport.http',
            params={'JANUS_API_PORT': self._janus_api_port})
        self._process_config_file(
            name='janus.transport.websockets',
            params={'JANUS_WS_PORT': self._janus_ws_port})
        self._process_config_file(
            name='janus.plugin.streaming',
            params={'JANUS_VIDEO_PORT': self._janus_video_port})
        self._run_janus()
예제 #25
0
    def request_app_token(self):
        _logger.log('Octoprint API: Request app token')
        self.set_loading(True)

        class Response(APIProtocol):
            def __init__(self, p):
                self._p = p

            def on_succeed(self, data):
                self._p.polling_for_api_key(token=data['app_token'])

            def on_error(self, error):
                self._p.set_error(error)
                self._p.disconnect()

        self.set_step(Step.OCTOPRINT_OAUTH)
        self.octoprint_api.request_app_token(callback=Response(self))
예제 #26
0
    def disconnect(self):
        _logger.log('Janus: Disconnecting')

        if self._ws:
            self._ws.close()
            self._ws.keep_running = False
            self._ws_thread = None
            self._ws = None

        self._paused = False
        self._stream_on_start = False

        if self._janus_proc:
            try:
                self._janus_proc.terminate()
            except Exception as e:
                _logger.warn(e)

        self._janus_thread = None
예제 #27
0
    def probe_plugin_appkeys(self):
        _logger.log('Octoprint API: Probe plugin appkeys')
        self.set_loading(True)

        class Response(APIProtocol):
            def __init__(self, p):
                self._p = p

            def on_succeed(self, data):
                self._p.request_app_token()

            def on_error(self, error):
                self._p.set_error(
                    'You have to install Application Keys Plugin for grant access to Plabric or update your Octoprint version to version >= 1.3.10'
                )
                self._p.disconnect()

        self.set_step(Step.OCTOPRINT_OAUTH)
        self.octoprint_api.probe_plugin_appkeys(callback=Response(self))
예제 #28
0
    def connect(self):
        if self._enabled and not self.ws_connected():
            _logger.log('Janus: Connecting')

            def _on_error(ws, error):
                _logger.log('Janus Error: %s' % error)
                self._reset_janus_ws()

            def _on_message(ws, msg):
                self._process_msg(msg)

            def _on_close(ws):
                _logger.log('Janus: Ws Closed')
                self._callback.disconnected()
                self._reset_janus_ws()

            def _on_open(ws):
                _logger.log('Janus: Ws Opened')
                self._create_session()

            try:
                if self._janus_thread is None:
                    self._run_janus()

                if self._started_at is not None and time.time(
                ) - self._started_at < 4:
                    time.sleep(2)

                self._ws = websocket.WebSocketApp(
                    self._url,
                    on_open=_on_open,
                    on_message=_on_message,
                    on_close=_on_close,
                    on_error=_on_error,
                    subprotocols=['janus-protocol'])
                _ws_thread = threading.Thread(target=self._ws.run_forever)
                _ws_thread.daemon = True
                _ws_thread.start()

            except Exception as e:
                _logger.warn(e)
예제 #29
0
    def _process_config_file(self, name, params):
        janus_conf_template = os.path.join(self._janus_dir,
                                           'etc/janus/%s.jcfg.template' % name)
        janus_conf_path = os.path.join(self._janus_dir,
                                       'etc/janus/%s.jcfg' % name)
        if not os.path.isfile(janus_conf_template):
            _logger.log('Janus: Config file not found: %s' %
                        janus_conf_template)
            return

        with open(janus_conf_template, "rt") as fin:
            with open(janus_conf_path, "wt") as fout:
                for line in fin:
                    if len(line) > 0:
                        for key, value in params.items():
                            if key in line:
                                if value is None:
                                    line = '	#%s' % line
                                else:
                                    line = line.replace(
                                        '{%s}' % key, str(value))
                    fout.write(line)
예제 #30
0
    def _process_msg(self, msg):
        json = _json.loads(msg)
        if json['janus'] == 'ack':
            return

        _logger.log('Janus msg: %s' % json)

        if json['janus'] == 'success':
            if json['transaction'] == 'create':
                self._session_id = json['data']['id']
                self._attach_plugin()
            elif json['transaction'] == 'attach_plugin':
                self._handle_id = json['data']['id']
                self._send_to_janus(
                    data=_json.dumps({
                        'janus': 'keepalive',
                        'transaction': 'keepalive',
                        'session_id': self._session_id
                    }))
                self._update_streams_list()

            elif json['transaction'] == 'update_streams_list':
                self._streams = json['plugindata']['data']['list']
                if self._stream_on_start:
                    self.start_video_stream()

        if json['janus'] == 'event':
            if 'jsep' in json:
                self._send_session_description(json['jsep']['type'],
                                               json['jsep']['sdp'])

        if json['janus'] == 'hangup':
            _logger.log('Disconnected WebRTC')
            self._callback.wrtc_disconnected()

        if json['janus'] == 'webrtcup':
            _logger.log('Connected WebRTC')
            self._callback.wrtc_connected()

        if json['janus'] == 'event':
            if 'plugindata' in json and 'data' in json[
                    'plugindata'] and 'streaming' in json['plugindata']['data']:
                if json['plugindata']['data']['streaming'] == 'event':
                    if 'result' in json['plugindata']['data']:
                        if json['plugindata']['data']['result'][
                                'status'] == 'started':
                            self._callback.video_stream_started()