Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/server/mixins/webcam_server.py : 71%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2# This file is part of Xpra.
3# Copyright (C) 2010-2020 Antoine Martin <antoine@xpra.org>
4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
5# later version. See the file COPYING for details.
6#pylint: disable-msg=E1101
8import os.path
10from xpra.os_util import OSX, POSIX
11from xpra.util import engs
12from xpra.scripts.config import FALSE_OPTIONS
13from xpra.server.mixins.stub_server_mixin import StubServerMixin
14from xpra.log import Logger
16log = Logger("webcam")
19"""
20Mixin for servers that handle webcam forwarding,
21it just delegates to the webcam source mixin,
22so each user can have its own webcam device(s).
23"""
24class WebcamServer(StubServerMixin):
26 def __init__(self):
27 self.webcam_device = ""
28 self.webcam_encodings = []
29 self.webcam_enabled = False
30 self.webcam_virtual_video_devices = 0
32 def init(self, opts):
33 self.webcam_enabled = opts.webcam.lower() not in FALSE_OPTIONS
34 if os.path.isabs(opts.webcam):
35 self.webcam_device = opts.webcam
37 def init_state(self):
38 #duplicated
39 self.readonly = False
41 def threaded_setup(self):
42 self.init_webcam()
45 def get_server_features(self, _source) -> dict:
46 return {
47 "webcam" : self.webcam_enabled,
48 "webcam.encodings" : self.webcam_encodings,
49 "virtual-video-devices" : self.webcam_virtual_video_devices,
50 }
53 def get_info(self, _proto) -> dict:
54 info = {
55 "" : self.webcam_enabled,
56 }
57 if self.webcam_enabled:
58 info.update({
59 "encodings" : self.webcam_encodings,
60 "virtual-video-devices" : self.webcam_virtual_video_devices,
61 })
62 if self.webcam_device:
63 info["device"] = self.webcam_device
64 return {"webcam" : info}
67 def init_webcam(self):
68 if not self.webcam_enabled:
69 return
70 try:
71 from xpra.codecs.pillow.decoder import get_encodings
72 self.webcam_encodings = tuple(x for x in ("png", "jpeg", "webp") if x in get_encodings())
73 except Exception as e:
74 log.error("Error: webcam forwarding disabled:")
75 log.error(" %s", e)
76 self.webcam_enabled = False
77 if self.webcam_device:
78 self.webcam_virtual_video_devices = 1
79 else:
80 self.webcam_virtual_video_devices = self.init_virtual_video_devices()
81 if self.webcam_virtual_video_devices==0:
82 self.webcam_enabled = False
84 def init_virtual_video_devices(self):
85 log("init_virtual_video_devices")
86 if not POSIX or OSX:
87 return 0
88 try:
89 from xpra.codecs.v4l2.pusher import Pusher
90 assert Pusher
91 except ImportError as e:
92 log.error("Error: failed to import the virtual video module:")
93 log.error(" %s", e)
94 return 0
95 try:
96 from xpra.platform.xposix.webcam import get_virtual_video_devices, check_virtual_dir
97 except ImportError as e:
98 log.warn("Warning: cannot load webcam components")
99 log.warn(" %s", e)
100 log.warn(" webcam forwarding disabled")
101 return 0
102 check_virtual_dir()
103 devices = get_virtual_video_devices()
104 log.info("found %i virtual video device%s for webcam forwarding", len(devices), engs(devices))
105 return len(devices)
107 def _process_webcam_start(self, proto, packet):
108 if self.readonly:
109 return
110 assert self.webcam_enabled
111 ss = self.get_server_source(proto)
112 if not ss:
113 log.warn("Warning: invalid client source for webcam start")
114 return
115 device_id, w, h = packet[1:4]
116 ss.start_virtual_webcam(device_id, w, h)
118 def _process_webcam_stop(self, proto, packet):
119 if self.readonly:
120 return
121 ss = self.get_server_source(proto)
122 if not ss:
123 log.warn("Warning: invalid client source for webcam start")
124 return
125 device_id, message = (list(packet)+[""])[1:3]
126 ss.stop_virtual_webcam(device_id, message)
128 def _process_webcam_frame(self, proto, packet):
129 if self.readonly:
130 return
131 ss = self.get_server_source(proto)
132 if not ss:
133 log.warn("Warning: invalid client source for webcam frame")
134 return
135 device_id, frame_no, encoding, w, h, data = packet[1:7]
136 ss.process_webcam_frame(device_id, frame_no, encoding, w, h, data)
138 def init_packet_handlers(self):
139 if self.webcam_enabled:
140 self.add_packet_handlers({
141 "webcam-start" : self._process_webcam_start,
142 "webcam-stop" : self._process_webcam_stop,
143 "webcam-frame" : self._process_webcam_frame,
144 }, False)