Skip to content

Commit b6f6f77

Browse files
committed
set default frame size
#90
1 parent f0c8e8d commit b6f6f77

File tree

4 files changed

+33
-45
lines changed

4 files changed

+33
-45
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Docker container to expose a local RTMP, RTSP, and HLS stream for all your Wyze
99

1010
Based on [@noelhibbard's script](https://gist.github.com/noelhibbard/03703f551298c6460f2fd0bfdbc328bd#file-readme-md) with [kroo/wyzecam](https://github.com/kroo/wyzecam), and [aler9/rtsp-simple-server](https://github.com/aler9/rtsp-simple-server).
1111

12+
## Changes in v0.6.5
13+
14+
- 🔨 Always set default frame size and bitrate to prevent restart loop.
15+
1216
## Changes in v0.6.4
1317

1418
- 🐛 BUG: Fixed the issue introduced in v0.6.2 where a resolution change caused issues for RTMP and HLS streams. This will now raise an exception which *should* restart ffmpeg if the resolution doesn't match for more than 30 frames.

app/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## Changes in v0.6.5
2+
3+
- 🔨 Always set default frame size and bitrate to prevent restart loop.
4+
15
## Changes in v0.6.4
26

37
- 🐛 BUG: Fixed the issue introduced in v0.6.2 where a resolution change caused issues for RTMP and HLS streams. This will now raise an exception which *should* restart ffmpeg if the resolution doesn't match for more than 30 frames.

app/config.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"slug": "docker-wyze-bridge",
55
"url": "http://github.com/mrlt8/docker-wyze-bridge",
66
"image": "mrlt8/wyze-bridge",
7-
"version": "0.6.4",
7+
"version": "0.6.5",
88
"arch": [
99
"armv7",
1010
"aarch64",
@@ -32,8 +32,8 @@
3232
"options": {
3333
"WYZE_EMAIL": null,
3434
"WYZE_PASSWORD": null,
35-
"API_THUMB": true,
36-
"LAN_ONLY": true
35+
"LAN_ONLY": true,
36+
"API_THUMB": true
3737
},
3838
"schema": {
3939
"WYZE_EMAIL": "email",

app/wyze_bridge.py

+22-42
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import gc
22
import logging
3-
from types import resolve_bases
43
import mintotp
54
import os
65
import pickle
@@ -18,17 +17,17 @@ def __init__(self) -> None:
1817
self.img_path = "/img/"
1918

2019
def run(self) -> None:
21-
print("\n🚀 STARTING DOCKER-WYZE-BRIDGE v0.6.4")
20+
print("\n🚀 STARTING DOCKER-WYZE-BRIDGE v0.6.5")
2221
if os.environ.get("HASS"):
2322
print("\n🏠 Home Assistant Mode")
2423
self.token_path = "/config/wyze-bridge/"
2524
self.img_path = "/config/www/"
2625
os.makedirs("/config/www/", exist_ok=True)
2726
os.makedirs(self.token_path, exist_ok=True)
2827
open(self.token_path + "mfa_token.txt", "w").close()
29-
if self.env_bool("FILTER_MODE"):
28+
if os.getenv("FILTER_MODE"):
3029
print("\n\n⚠️ 'FILTER_MODE' DEPRECATED.\nUSE 'FILTER_BLOCK' INSTEAD\n")
31-
if self.env_bool("FILTER_MODEL"):
30+
if os.getenv("FILTER_MODEL"):
3231
print("\n\n⚠️ 'FILTER_MODEL' DEPRECATED.\nUSE 'FILTER_MODELS' INSTEAD\n")
3332
self.user = self.get_wyze_data("user")
3433
self.cameras = self.get_filtered_cams()
@@ -42,7 +41,6 @@ def run(self) -> None:
4241
).start()
4342

4443
mode = {0: "P2P", 1: "RELAY", 2: "LAN"}
45-
res = {"1": "1080p", "2": "360p", "3": "HD", "4": "SD"}
4644
model_names = {
4745
"WYZECP1_JEF": "PAN",
4846
"WYZEC1": "V1",
@@ -52,8 +50,8 @@ def run(self) -> None:
5250
"WVOD1": "OUTDOOR",
5351
}
5452

55-
def env_bool(self, env: str) -> str:
56-
return os.environ.get(env, "").lower().replace("false", "")
53+
def env_bool(self, env: str, false: str = "") -> str:
54+
return os.environ.get(env.upper(), false).lower().replace("false", "") or false
5755

5856
def env_list(self, env: str) -> list:
5957
if "," in os.getenv(env, ""):
@@ -242,24 +240,16 @@ def get_filtered_cams(self) -> list:
242240

243241
def start_stream(self, camera) -> None:
244242
uri = self.clean_name(camera.nickname)
245-
iotc = [self.iotc.tutk_platform_lib, self.user, camera]
246-
resolution = 0
247-
bitrate = 120
248-
res = "HD"
249243
if self.env_bool("RTSP_THUMB") and self.env_bool("RTSP_API"):
250244
self.save_rtsp_thumb(uri)
251245
elif self.env_bool("API_THUMB") and getattr(camera, "thumbnail", False):
252246
self.save_api_thumb(camera)
253-
if self.env_bool("QUALITY"):
254-
quality = os.environ["QUALITY"]
255-
if "SD" in quality[:2].upper():
256-
resolution = 1
257-
res = "SD"
258-
if quality[2:].isdigit() and 30 <= int(quality[2:]) <= 255:
259-
bitrate = int(quality[2:])
260-
iotc.extend((resolution, bitrate))
261-
if camera.product_model in "WYZEDB3":
262-
resolution += 3
247+
env_q = self.env_bool("QUALITY", "na").upper().ljust(3, "0")
248+
res_size = 1 if "SD" in env_q[:2] else 0
249+
bitrate = int(env_q[2:]) if 30 <= int(env_q[2:]) <= 255 else 120
250+
stream = f'{"360p" if res_size == 1 else "1080p"} {bitrate}kb/s Stream'
251+
res_size += 3 if camera.product_model in "WYZEDB3" else 0
252+
iotc = [self.iotc.tutk_platform_lib, self.user, camera, res_size, bitrate]
263253
while True:
264254
try:
265255
log.debug("⌛️ Connecting to cam..")
@@ -270,20 +260,12 @@ def start_stream(self, camera) -> None:
270260
log.warning(
271261
f'☁️ WARNING: Camera is connected via "{self.mode.get(sess.session_check().mode,f"UNKNOWN ({sess.session_check().mode})")} mode". Stream may consume additional bandwidth!'
272262
)
273-
if sess.camera.camera_info.get("videoParm", False):
274-
vidparm = sess.camera.camera_info["videoParm"]
275-
if self.env_bool("DEBUG_LEVEL"):
276-
log.info(f"[videoParm] {vidparm}")
277-
res = self.res.get(
278-
vidparm.get("resolution", 0), f"RES-{vidparm['resolution']}"
279-
)
280-
stream = f"{res} {vidparm.get('bitRate', 0)}kb/s Stream"
281-
elif self.env_bool("QUALITY"):
282-
stream = f"{res} {bitrate}kb/s Stream"
283-
else:
284-
stream = "Stream"
263+
if self.env_bool("DEBUG_LEVEL") and sess.camera.camera_info.get(
264+
"videoParm", False
265+
):
266+
log.info(f"[videoParm] {sess.camera.camera_info['videoParm']}")
285267
log.info(
286-
f'🎉 Starting {stream} for WyzeCam {self.model_names.get(camera.product_model,camera.product_model)} in "{self.mode.get(sess.session_check().mode,f"UNKNOWN ({sess.session_check().mode})")} mode" FW: {sess.camera.camera_info["basicInfo"]["firmware"]} IP: {camera.ip} WiFi: {sess.camera.camera_info["basicInfo"].get("wifidb", "NA")}%'
268+
f'🎉 Starting {stream} for WyzeCam {self.model_names.get(camera.product_model,camera.product_model)} in "{self.mode.get(sess.session_check().mode,f"UNKNOWN ({sess.session_check().mode})")} mode" FW: {sess.camera.camera_info["basicInfo"].get("firmware","NA")} IP: {camera.ip} WiFi: {sess.camera.camera_info["basicInfo"].get("wifidb", "NA")}%'
287269
)
288270
cmd = self.get_ffmpeg_cmd(uri)
289271
if "ffmpeg" not in cmd[0].lower():
@@ -297,14 +279,14 @@ def start_stream(self, camera) -> None:
297279
skipped = 0
298280
for (frame, info) in sess.recv_video_data():
299281
try:
300-
if skipped > os.getenv("BAD_FRAMES", 30):
301-
raise Exception("Wrong resolution")
302-
if resolution != info.frame_size and not self.env_bool(
282+
if skipped >= os.getenv("BAD_FRAMES", 30):
283+
raise Exception(f"Wrong resolution: {info.frame_size}")
284+
if res_size != info.frame_size and not self.env_bool(
303285
"IGNORE_RES"
304286
):
305287
skipped += 1
306288
log.debug(
307-
f"wrong resolution exp: {resolution} got:{info.frame_size} ({skipped} times)"
289+
f"Bad frame resolution: {res_size} != {info.frame_size} [{skipped}]"
308290
)
309291
continue
310292
ffmpeg.stdin.write(frame)
@@ -357,14 +339,14 @@ def get_ffmpeg_cmd(self, uri: str) -> list:
357339
"-vcodec",
358340
"copy",
359341
"-rtsp_transport",
360-
os.getenv("RTSP_PROTOCOLS", "tcp"),
342+
self.env_bool("RTSP_PROTOCOLS", "tcp"),
361343
"-f",
362344
"rtsp",
363345
"rtsp://"
364346
+ (
365347
"0.0.0.0" + os.getenv("RTSP_RTSPADDRESS")
366348
if os.getenv("RTSP_RTSPADDRESS", "").startswith(":")
367-
else os.getenv("RTSP_RTSPADDRESS", "0.0.0.0:8554")
349+
else self.env_bool("RTSP_RTSPADDRESS", "0.0.0.0:8554")
368350
),
369351
]
370352
)
@@ -394,10 +376,8 @@ def get_ffmpeg_cmd(self, uri: str) -> list:
394376
logging.getLogger().setLevel(debug_level)
395377
log = logging.getLogger("wyze_bridge")
396378
log.setLevel(debug_level if "DEBUG_LEVEL" in os.environ else logging.INFO)
397-
398379
if wb.env_bool("DEBUG_FRAMES"):
399380
warnings.simplefilter("always")
400381
warnings.formatwarning = lambda msg, *args, **kwargs: f"WARNING: {msg}"
401382
logging.captureWarnings(True)
402-
403383
wb.run()

0 commit comments

Comments
 (0)