Skip to content

Commit

Permalink
set default frame size
Browse files Browse the repository at this point in the history
  • Loading branch information
mrlt8 committed Sep 10, 2021
1 parent f0c8e8d commit b6f6f77
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 45 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Docker container to expose a local RTMP, RTSP, and HLS stream for all your Wyze

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).

## Changes in v0.6.5

- 🔨 Always set default frame size and bitrate to prevent restart loop.

## Changes in v0.6.4

- 🐛 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.
Expand Down
4 changes: 4 additions & 0 deletions app/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## Changes in v0.6.5

- 🔨 Always set default frame size and bitrate to prevent restart loop.

## Changes in v0.6.4

- 🐛 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.
Expand Down
6 changes: 3 additions & 3 deletions app/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"slug": "docker-wyze-bridge",
"url": "http://github.com/mrlt8/docker-wyze-bridge",
"image": "mrlt8/wyze-bridge",
"version": "0.6.4",
"version": "0.6.5",
"arch": [
"armv7",
"aarch64",
Expand Down Expand Up @@ -32,8 +32,8 @@
"options": {
"WYZE_EMAIL": null,
"WYZE_PASSWORD": null,
"API_THUMB": true,
"LAN_ONLY": true
"LAN_ONLY": true,
"API_THUMB": true
},
"schema": {
"WYZE_EMAIL": "email",
Expand Down
64 changes: 22 additions & 42 deletions app/wyze_bridge.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import gc
import logging
from types import resolve_bases
import mintotp
import os
import pickle
Expand All @@ -18,17 +17,17 @@ def __init__(self) -> None:
self.img_path = "/img/"

def run(self) -> None:
print("\n🚀 STARTING DOCKER-WYZE-BRIDGE v0.6.4")
print("\n🚀 STARTING DOCKER-WYZE-BRIDGE v0.6.5")
if os.environ.get("HASS"):
print("\n🏠 Home Assistant Mode")
self.token_path = "/config/wyze-bridge/"
self.img_path = "/config/www/"
os.makedirs("/config/www/", exist_ok=True)
os.makedirs(self.token_path, exist_ok=True)
open(self.token_path + "mfa_token.txt", "w").close()
if self.env_bool("FILTER_MODE"):
if os.getenv("FILTER_MODE"):
print("\n\n⚠️ 'FILTER_MODE' DEPRECATED.\nUSE 'FILTER_BLOCK' INSTEAD\n")
if self.env_bool("FILTER_MODEL"):
if os.getenv("FILTER_MODEL"):
print("\n\n⚠️ 'FILTER_MODEL' DEPRECATED.\nUSE 'FILTER_MODELS' INSTEAD\n")
self.user = self.get_wyze_data("user")
self.cameras = self.get_filtered_cams()
Expand All @@ -42,7 +41,6 @@ def run(self) -> None:
).start()

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

def env_bool(self, env: str) -> str:
return os.environ.get(env, "").lower().replace("false", "")
def env_bool(self, env: str, false: str = "") -> str:
return os.environ.get(env.upper(), false).lower().replace("false", "") or false

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

def start_stream(self, camera) -> None:
uri = self.clean_name(camera.nickname)
iotc = [self.iotc.tutk_platform_lib, self.user, camera]
resolution = 0
bitrate = 120
res = "HD"
if self.env_bool("RTSP_THUMB") and self.env_bool("RTSP_API"):
self.save_rtsp_thumb(uri)
elif self.env_bool("API_THUMB") and getattr(camera, "thumbnail", False):
self.save_api_thumb(camera)
if self.env_bool("QUALITY"):
quality = os.environ["QUALITY"]
if "SD" in quality[:2].upper():
resolution = 1
res = "SD"
if quality[2:].isdigit() and 30 <= int(quality[2:]) <= 255:
bitrate = int(quality[2:])
iotc.extend((resolution, bitrate))
if camera.product_model in "WYZEDB3":
resolution += 3
env_q = self.env_bool("QUALITY", "na").upper().ljust(3, "0")
res_size = 1 if "SD" in env_q[:2] else 0
bitrate = int(env_q[2:]) if 30 <= int(env_q[2:]) <= 255 else 120
stream = f'{"360p" if res_size == 1 else "1080p"} {bitrate}kb/s Stream'
res_size += 3 if camera.product_model in "WYZEDB3" else 0
iotc = [self.iotc.tutk_platform_lib, self.user, camera, res_size, bitrate]
while True:
try:
log.debug("⌛️ Connecting to cam..")
Expand All @@ -270,20 +260,12 @@ def start_stream(self, camera) -> None:
log.warning(
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!'
)
if sess.camera.camera_info.get("videoParm", False):
vidparm = sess.camera.camera_info["videoParm"]
if self.env_bool("DEBUG_LEVEL"):
log.info(f"[videoParm] {vidparm}")
res = self.res.get(
vidparm.get("resolution", 0), f"RES-{vidparm['resolution']}"
)
stream = f"{res} {vidparm.get('bitRate', 0)}kb/s Stream"
elif self.env_bool("QUALITY"):
stream = f"{res} {bitrate}kb/s Stream"
else:
stream = "Stream"
if self.env_bool("DEBUG_LEVEL") and sess.camera.camera_info.get(
"videoParm", False
):
log.info(f"[videoParm] {sess.camera.camera_info['videoParm']}")
log.info(
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")}%'
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")}%'
)
cmd = self.get_ffmpeg_cmd(uri)
if "ffmpeg" not in cmd[0].lower():
Expand All @@ -297,14 +279,14 @@ def start_stream(self, camera) -> None:
skipped = 0
for (frame, info) in sess.recv_video_data():
try:
if skipped > os.getenv("BAD_FRAMES", 30):
raise Exception("Wrong resolution")
if resolution != info.frame_size and not self.env_bool(
if skipped >= os.getenv("BAD_FRAMES", 30):
raise Exception(f"Wrong resolution: {info.frame_size}")
if res_size != info.frame_size and not self.env_bool(
"IGNORE_RES"
):
skipped += 1
log.debug(
f"wrong resolution exp: {resolution} got:{info.frame_size} ({skipped} times)"
f"Bad frame resolution: {res_size} != {info.frame_size} [{skipped}]"
)
continue
ffmpeg.stdin.write(frame)
Expand Down Expand Up @@ -357,14 +339,14 @@ def get_ffmpeg_cmd(self, uri: str) -> list:
"-vcodec",
"copy",
"-rtsp_transport",
os.getenv("RTSP_PROTOCOLS", "tcp"),
self.env_bool("RTSP_PROTOCOLS", "tcp"),
"-f",
"rtsp",
"rtsp://"
+ (
"0.0.0.0" + os.getenv("RTSP_RTSPADDRESS")
if os.getenv("RTSP_RTSPADDRESS", "").startswith(":")
else os.getenv("RTSP_RTSPADDRESS", "0.0.0.0:8554")
else self.env_bool("RTSP_RTSPADDRESS", "0.0.0.0:8554")
),
]
)
Expand Down Expand Up @@ -394,10 +376,8 @@ def get_ffmpeg_cmd(self, uri: str) -> list:
logging.getLogger().setLevel(debug_level)
log = logging.getLogger("wyze_bridge")
log.setLevel(debug_level if "DEBUG_LEVEL" in os.environ else logging.INFO)

if wb.env_bool("DEBUG_FRAMES"):
warnings.simplefilter("always")
warnings.formatwarning = lambda msg, *args, **kwargs: f"WARNING: {msg}"
logging.captureWarnings(True)

wb.run()

0 comments on commit b6f6f77

Please sign in to comment.