Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2.3.11 #926

Merged
merged 22 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 56 additions & 90 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,27 @@ on:
workflow_dispatch:

jobs:
prebuild:
runs-on: ubuntu-latest
steps:
- name: Should build?
run: |
if [ -z "${{ secrets.DOCKERHUB_USERNAME }}" ]; then
echo "The DOCKERHUB_USERNAME secret is missing."
exit 1
fi

build:
needs: [prebuild]
runs-on: ubuntu-latest
permissions:
contents: write
packages: write

strategy:
matrix:
dockerfile: ['multiarch', 'hwaccel', 'qsv']

steps:
- name: Checkout repository
uses: actions/checkout@v3
Expand All @@ -38,8 +53,6 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ghcr.io
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
Expand All @@ -48,126 +61,79 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: matrix image type
id: image_type
run: |
echo "suffix=${{ matrix.dockerfile == 'hwaccel' && '-hw' || matrix.dockerfile == 'qsv' && '-qsv' ||'' }}" >> $GITHUB_OUTPUT
echo "platforms=${{ matrix.dockerfile == 'multiarch' && 'linux/amd64,linux/arm64,linux/arm' || 'linux/amd64' }}" >> $GITHUB_OUTPUT
echo "arch=${{ matrix.dockerfile == 'multiarch' && 'amd64,armhf,aarch64' || 'amd64' }}" >> $GITHUB_OUTPUT

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v4
with:
images: |
${{ github.repository_owner }}/wyze-bridge
ghcr.io/${{ github.repository }}
tags: |
type=schedule
type=semver,pattern={{ version }}
type=edge,branch=main,enable=${{ github.event_name == 'push' }}
type=ref,event=branch,enable=${{ contains(github.ref,'dev') }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata for hwaccel builds
id: hwmeta
uses: docker/metadata-action@v4
with:
images: |
${{ github.repository_owner }}/wyze-bridge
ghcr.io/${{ github.repository }}
flavor: |
latest=auto
suffix=-hw,onlatest=true
tags: |
type=schedule,suffix=-hw
type=semver,pattern={{ version }},suffix=-hw
type=edge,branch=main,enable=${{ github.event_name == 'push' }},suffix=-hw
type=ref,event=branch,enable=${{ contains(github.ref,'dev') }},suffix=-hw

- name: Extract Docker metadata for qsv builds
id: qsvmeta
uses: docker/metadata-action@v4
with:
images: |
${{ github.repository_owner }}/wyze-bridge
ghcr.io/${{ github.repository }}
flavor: |
latest=auto
suffix=-qsv,onlatest=true
suffix=${{ steps.image_type.outputs.suffix }},onlatest=true
tags: |
type=schedule,suffix=-qsv
type=semver,pattern={{ version }},suffix=-qsv
type=edge,branch=main,enable=${{ github.event_name == 'push' }},suffix=-qsv
type=ref,event=branch,enable=${{ contains(github.ref,'dev') }},suffix=-qsv
type=schedule,suffix=${{ steps.image_type.outputs.suffix }}
type=semver,pattern={{ version }},suffix=${{ steps.image_type.outputs.suffix }}
type=edge,branch=main,enable=${{ github.event_name == 'push' }},suffix=${{ steps.image_type.outputs.suffix }}
type=ref,event=branch,enable=${{ contains(github.ref,'dev') }},suffix=${{ steps.image_type.outputs.suffix }}

- name: Update Release Version
if: steps.meta.outputs.VERSION != ''
id: version_bump
if: startsWith(github.ref, 'refs/tags/v')
run: |
if [[ ${{ steps.meta.outputs.VERSION }} =~ ^[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
sed -i "s/^VERSION=.*/VERSION=${{ steps.meta.outputs.VERSION }}/" ./app/.env
jq --arg VERSION "${{ steps.meta.outputs.VERSION }}" '.version = $VERSION' ./app/config.json > updated.json
TAG_NAME=${GITHUB_REF##*/v}
if [[ $TAG_NAME =~ ^[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
sed -i "s/^VERSION=.*/VERSION=${TAG_NAME}/" ./app/.env
jq --arg VERSION "${TAG_NAME}" '.version = $VERSION' ./app/config.json > updated.json
mv updated.json ./app/config.json
fi

# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push a multi-arch Docker image
- name: Build and push a Docker image
uses: docker/build-push-action@v4
with:
builder: ${{ steps.buildx.outputs.name }}
context: ./app/
push: ${{ github.event_name != 'pull_request' }}
file: ./app/Dockerfile.multiarch
platforms: linux/amd64,linux/arm64,linux/arm
file: ./app/Dockerfile.${{ matrix.dockerfile }}
platforms: ${{ steps.image_type.outputs.platforms }}
build-args: BUILD=${{ steps.meta.outputs.VERSION }}
labels: |
${{ steps.meta.outputs.labels }}
io.hass.name=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.title'] }}
io.hass.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }}
io.hass.version=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
io.hass.type=addon
io.hass.arch=amd64,armhf,aarch64
io.hass.arch=${{ steps.image_type.outputs.arch }}
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max

# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push an amd64 Docker image with hwaccel enabled
uses: docker/build-push-action@v4
with:
builder: ${{ steps.buildx.outputs.name }}
context: ./app/
push: ${{ github.event_name != 'pull_request' }}
file: ./app/Dockerfile.hwaccel
platforms: linux/amd64
build-args: BUILD=${{ steps.meta.outputs.VERSION }}
labels: |
${{ steps.meta.outputs.labels }}
io.hass.name=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.title'] }}
io.hass.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }}
io.hass.version=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
io.hass.type=addon
io.hass.arch=amd64
tags: ${{ steps.hwmeta.outputs.tags }}

- name: Build and push an amd64 Docker image with QSV drivers
uses: docker/build-push-action@v4
with:
builder: ${{ steps.buildx.outputs.name }}
context: ./app/
push: ${{ github.event_name != 'pull_request' }}
file: ./app/Dockerfile.hwaccel
build-args: |
BUILD=${{ steps.meta.outputs.VERSION }}
QSV=1
labels: |
${{ steps.meta.outputs.labels }}
io.hass.name=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.title'] }}
io.hass.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }}
io.hass.version=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
io.hass.type=addon
io.hass.arch=amd64
tags: ${{ steps.qsvmeta.outputs.tags }}

version_bump:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Update Release Version
id: version_bump
if: startsWith(github.ref, 'refs/tags/v')
run: |
TAG_NAME=${GITHUB_REF##*/v}
if [[ $TAG_NAME =~ ^[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
sed -i "s/^VERSION=.*/VERSION=${TAG_NAME}/" ./app/.env
jq --arg VERSION "${TAG_NAME}" '.version = $VERSION' ./app/config.json > updated.json
mv updated.json ./app/config.json
echo "tag=${TAG_NAME}" >> $GITHUB_OUTPUT
fi
- name: Commit and push changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
branch: main
commit_message: 'Bump Version to v${{ steps.meta.outputs.VERSION }}'
commit_message: 'Bump Version to v${{ steps.version_bump.outputs.tag }}'
file_pattern: 'app/.env app/config.json'
38 changes: 19 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,26 @@ You can then use the web interface at `http://localhost:5000` where localhost is

See [basic usage](#basic-usage) for additional information or visit the [wiki page](https://github.com/mrlt8/docker-wyze-bridge/wiki/Home-Assistant) for additional information on using the bridge as a Home Assistant Add-on.

## What's Changed in v2.3.10

* FIX: KeyError when upgrading with old cache data in v2.3.9 (#905) Thanks @itsamenathan!
* You should be able to remove or set `FRESH_DATA` back to false.
* MQTT: Update bridge status (#907) Thanks @giorgi1324!

## What's Changed in v2.3.9

* NEW: ENV Options - token-based authentication (#876)
* `REFRESH_TOKEN` - Use a valid refresh token to request a *new* access token and refresh token.
* `ACCESS_TOKEN` - Use an existing valid access token too access the API. Will *not* be able to refresh the token once it expires.
* NEW: Docker "QSV" Images with basic support for QSV hardware accelerated encoding. (#736) Thanks @mitchross, @392media, @chris001, and everyone who helped!
* Use the `latest-qsv` tag (e.g., `mrlt8/wyze-bridge:latest-qsv`) along with the `H264_ENC=h264_qsv` ENV variable.
## What's Changed in v2.3.11

* NEW:
* Add more MQTT entities when using MQTT discovery. Thanks @jhansche! #921 #922
* custom video filter - Use `FFMPEG_FILTER` or `FFMPEG_FILTER_CAM-NAME` to set custom ffmpeg video filters. #919
* NEW MQTT/REST commands:
* **SET** topic: `cruise_point` | payload: (int) 1-4 - Pan to predefined cruise_point/waypoint. Thanks @jhansche! (#835).
* **SET** topic: `time_zone` | payload: (str) `Area/Location`, e.g. `America/New_York` - Change camera timezone. Thanks @DennisGarvey! (#916)
* **GET/SET** topic: `osd_timestamp` | payload: (bool/int) `on/off` - toggle timestamp on video.
* **GET/SET** topic: `osd_logo` | payload: (bool/int) `on/off` - toggle wyze logo on video.
* **SET** topic: `quick_reponse` | payload: (int) 1-3 - Doorbell quick response.
* FIXES:
* Home Assistant: set max bitrate quality to 255 (#893) Thanks @gtxaspec!
* WebUI: email 2FA support.
* UPDATES:
* Docker base image: bullseye -> bookworm
* MediaMTX: v0.23.6 -> v0.23.7
* Wyze App: v2.42.6.1 -> v2.43.0.12
* Resend discovery message on HA online. Thanks @jhansche! #907 #920
* Return json response/value for commands. Thanks @jhansche! #835
* Fix threading issue on restart. Thanks @ZacTyAdams! #902
* Catch and disable MQTT on name resolution error.
* Fix SET cruise_points over MQTT.
* Updates:
* Wyze iOS App version from v2.43.0.12 to v2.43.5.3 (#914)
* MediaMTX version from v0.23.7 to v0.23.8 (#925)


[View previous changes](https://github.com/mrlt8/docker-wyze-bridge/releases)
Expand Down
21 changes: 21 additions & 0 deletions app/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
## What's Changed in v2.3.11

* NEW:
* Add more MQTT entities when using MQTT discovery. Thanks @jhansche! #921 #922
* custom video filter - Use `FFMPEG_FILTER` or `FFMPEG_FILTER_CAM-NAME` to set custom ffmpeg video filters. #919
* NEW MQTT/REST commands:
* **SET** topic: `cruise_point` | payload: (int) 1-4 - Pan to predefined cruise_point/waypoint. Thanks @jhansche! (#835).
* **SET** topic: `time_zone` | payload: (str) `Area/Location`, e.g. `America/New_York` - Change camera timezone. Thanks @DennisGarvey! (#916)
* **GET/SET** topic: `osd_timestamp` | payload: (bool/int) `on/off` - toggle timestamp on video.
* **GET/SET** topic: `osd_logo` | payload: (bool/int) `on/off` - toggle wyze logo on video.
* **SET** topic: `quick_reponse` | payload: (int) 1-3 - Doorbell quick response.
* FIXES:
* Resend discovery message on HA online. Thanks @jhansche! #907 #920
* Return json response/value for commands. Thanks @jhansche! #835
* Fix threading issue on restart. Thanks @ZacTyAdams! #902
* Catch and disable MQTT on name resolution error.
* Fix SET cruise_points over MQTT.
* Updates:
* Wyze iOS App version from v2.43.0.12 to v2.43.5.3 (#914)
* MediaMTX version from v0.23.7 to v0.23.8 (#925)

## What's Changed in v2.3.10

* FIX: KeyError when upgrading with old cache data in v2.3.9 (#905) Thanks @itsamenathan!
Expand Down
2 changes: 1 addition & 1 deletion app/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def api_cam(cam_name: str):
return {"error": f"Could not find camera [{cam_name}]"}

@app.route("/api/<cam_name>/<cam_cmd>", methods=["GET", "PUT", "POST"])
@app.route("/api/<cam_name>/<cam_cmd>/<payload>")
@app.route("/api/<cam_name>/<cam_cmd>/<path:payload>")
def api_cam_control(cam_name: str, cam_cmd: str, payload: str | dict = ""):
"""API Endpoint to send tutk commands to the camera."""
if args := request.values:
Expand Down
20 changes: 13 additions & 7 deletions app/wyzebridge/ffmpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,30 +91,36 @@ def re_encode_video(uri: str, is_vertical: bool) -> list[str]:

"""
h264_enc: str = env_bool("h264_enc", "libx264")
rotation = []
custom_filter = env_cam("FFMPEG_FILTER", uri)
v_filter = []
transpose = "clock"
if (env_bool("ROTATE_DOOR") and is_vertical) or env_bool(f"ROTATE_CAM_{uri}"):
if os.getenv(f"ROTATE_CAM_{uri}") in {"0", "1", "2", "3"}:
# Numerical values are deprecated, and should be dropped
# in favor of symbolic constants.
transpose = os.environ[f"ROTATE_CAM_{uri}"]

rotation = ["-filter:v", f"transpose={transpose}"]
v_filter = ["-filter:v", f"transpose={transpose}"]
if h264_enc == "h264_vaapi":
rotation[1] = f"transpose_vaapi={transpose}"
v_filter[1] = f"transpose_vaapi={transpose}"
elif h264_enc == "h264_qsv":
rotation[1] = f"vpp_qsv=transpose={transpose}"
v_filter[1] = f"vpp_qsv=transpose={transpose}"

if not env_bool("FORCE_ENCODE") and not rotation:
if not env_bool("FORCE_ENCODE") and not v_filter and not custom_filter:
return ["copy"]

logger.info(
f"Re-encoding using {h264_enc}{f' [{transpose=}]' if rotation else '' }"
f"Re-encoding using {h264_enc}{f' [{transpose=}]' if v_filter else '' }"
)
if custom_filter:
v_filter = [
"-filter:v",
f"{v_filter[1]},{custom_filter}" if v_filter else custom_filter,
]

return (
[h264_enc]
+ rotation
+ v_filter
+ ["-b:v", "2000k", "-coder", "1", "-bufsize", "2000k"]
+ ["-profile:v", "77" if h264_enc == "h264_v4l2m2m" else "main"]
+ ["-preset", "fast" if h264_enc in {"h264_nvenc", "h264_qsv"} else "ultrafast"]
Expand Down
Loading
Loading