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

SUGGESTION: Add more details to the cams.m3u8 file #1414

Open
IDisposable opened this issue Jan 24, 2025 · 4 comments
Open

SUGGESTION: Add more details to the cams.m3u8 file #1414

IDisposable opened this issue Jan 24, 2025 · 4 comments

Comments

@IDisposable
Copy link

IDisposable commented Jan 24, 2025

I'm trying to add all my Wyze Bridge-exposed cameras as a source in my Channels DVR for easy remote access. I discovered the cams.m3u8 endpoint which looks like a good starting point

#EXTM3U

#EXTINF:-1 channel-id="bird-camera" tvc-guide-genres="WYZE_CAKP2JFUS", bird-camera
http://home.example.com:8888/bird-camera/stream.m3u8

#EXTINF:-1 channel-id="coop-camera" tvc-guide-genres="WYZE_CAKP2JFUS", coop-camera
http://home.example.com:8888/coop-camera/stream.m3u8

#EXTINF:-1 channel-id="basement-camera" tvc-guide-genres="WYZE_CAKP2JFUS", basement-camera
http://home.example.com:8888/basement-camera/stream.m3u8

#EXTINF:-1 channel-id="driveway-camera" tvc-guide-genres="WYZE_CAKP2JFUS", driveway-camera
http://home.example.com:8888/driveway-camera/stream.m3u8

Creating a source in Channels DVR at Settings/Sources/Add Source/Custom Channels with a source type of HLS and a URL of http://home.example.com:5000/cams.m3u8 results in a UI like this in Channels DVR's Live TV view.

Image

This lacks a bit of umph :)

So I used a Text style custom channel definition like:

#EXTM3U

#EXTINF:-1 channel-id="driveway-camera" tvc-guide-genres="WYZE_CAKP2JFUS" tvc-guide-tags="Live" tvc-guide-placeholders="1800" tvg-logo="https://app-resource.wyze.com/device_image/new/wyze_icon_device_cam_v3.png" tvg-name="Driveway Camera" tvc-guide-title="Driveway Camera" tvc-guide-description="Live Driveway Camera" tvc-guide-art="http://home.example.com:5000/img/driveway-camera.png",driveway-camera
https://home.example.com:8888/driveway-camera/stream.m3u8

#EXTINF:-1 channel-id="coop-camera" tvc-guide-genres="cams,WYZE_CAKP2JFUS" tvc-guide-tags="Live" tvc-guide-placeholders="1800" tvg-logo="https://app-resource.wyze.com/device_image/new/wyze_icon_device_cam_v3.png" tvg-name="Coop Camera" tvc-guide-title="Coop Camera" tvc-guide-description="Live Coop Camera" tvc-guide-art="http://home.example.com:5000/img/coop-camera.png",coop-camera
https://home.example.com:8888/coop-camera/stream.m3u8

#EXTINF:-1 channel-id="basement-camera"  tvc-guide-genres="WYZE_CAKP2JFUS" tvc-guide-tags="Live" tvc-guide-placeholders="1800" tvg-logo="https://app-resource.wyze.com/device_image/new/wyze_icon_device_cam_v3.png" tvg-name="Basement Camera" tvc-guide-title="Basement Camera" tvc-guide-description="Live Basement Camera" tvc-guide-art="http://home.example.com:5000/img/basement-camera.png",basement-camera
https://home.example.com:8888/basement-camera/stream.m3u8

#EXTINF:-1 channel-id="bird-camera" tvc-guide-genres="WYZE_CAKP2JFUS" tvc-guide-tags="Live" tvc-guide-placeholders="1800" tvg-logo="https://app-resource.wyze.com/device_image/new/wyze_icon_device_cam_v3.png" tvg-name="Bird Camera" tvc-guide-title="Bird Camera" tvc-guide-description="Live Bird camera" tvc-guide-art="http://home.example.com:5000/img/bird-camera.png",bird-camera
https://home.example.com:8888/bird-camera/stream.m3u8

Which causes the current thumbnails and and names to look a lot nicer

Image

Image

Now obviously I can do this manually... but as I add other cameras I would have to revisit this.

Since it appears the cams.m3u8 endpoint is driven by a template file, it should be relatively easy to upgrade the output to include the other parameters that make the Channels DVR listing look so much better. They should be properties available already on the camera object when rendering the template or could be hard-coded.

I suspect I could easily make the template changes, but I'm deployed inside a docker container in Home Assistant, so not sure how to go about making that happen and test. I could blindly submit a PR for the suggested template change but don't know how to make a test of that :(

@IDisposable
Copy link
Author

IDisposable commented Jan 25, 2025

Note that the in the M3U8 file, the channel tags (description of the channel) is actually a comment because the line starts with a #, so there's no problem emitting extra tags

Standard Tags

The documented M3U8 standard tags that Channels DVR uses are here:

channel-id: REQUIRED unique ID for the channel
channel-number: display number for the channel
tvg-logo: channel logo url (4x3 aspect ratio)
tvg-name: channel callsign

For my hard-coded example above:
The channel-id is set to the camera name (lower-cased and spaces-to-hyphen adjusted)
The channel-number can be ignored in Channels, so we don't have to set those.
The tvg-name is set to the camera name (unadjusted)
I set tvg-logo to the Wyze 3 SVG icon from their assets server (which could break eventually), but could easily be something available on the camera object that I don't know about... we also don't have to emit it..

Image

Channels DVR Extensions

Channels DVR also supports a bunch of extensions to the tags documented here:

tvc-guide-title: guide item title
tvc-guide-description: guide item description
tvc-guide-art: guide item art url (4x3 aspect ratio)
tvc-guide-tags: guide item tags. comma delimited. example: "HDTV, Live"
tvc-guide-genres: guide item genres. comma delimited. example: "Action, Children"
tvc-guide-categories: guide item categories. comma delimited. strict options: Movie, Sports event, Series

In my example above I've set:
tvc-guide-title to the unadjusted camera name.
tvc-guide-description to the unadjusted camera name with Live prefixed... probably completely optional.
tvc-guide-art to the camera's static thumbnail exposed at http://homeurl:5000/art/camera_name.png (I have my Wyze Bridge set to emit .png not .jpg files. This is the BIG change that makes things so much nicer
tvc-guide-tags to "Live"
tvc-guide-genres to "WYZE_CAKP2JFUS" which mirrored what was originally being set (from camera model)

I also set the tvc-guide-placeholders to "1800" to "fake a new airing" every 1800 seconds completely arbitrary

@IDisposable
Copy link
Author

IDisposable commented Jan 25, 2025

Looks like this might be a reasonable replacement for the m3u8.html template

#EXTM3U
{% for name,camera in cameras.items() %}{% if camera.enabled %}
#EXTINF:-1 channel-id="{{name}}" tvc-guide-genres="{{camera.product_model}}, {{camera.model_name}}" tvc-guide-tags="Cam, Live" tvc-guide-title="{{camera.nickname}}" tvc-guide-description=="Live {{camera.nickname}}" tvc-guide-art="http://home.example.com:5000/{{camera.img_url}}", {{name}}
{{ camera.hls_url }}stream.m3u8
{% endif %}{% endfor %}

I added Cam to the tags, camera.model_name (e.g. V3) to the genres, and have hard-coded a base URL (it might be available in the context the template has, but I don't know that), The camera.img_url is a good relative path, but we need the :5000 port for static resources, so... hardcoded for now. This could also be tvc-guide-art="http://home.example.com:5000/img/{{name}}.png" (or .jpg) since that reduces down to the same thing. If we used /thumbinstead of/imgit looks to be the same file***... but using/snapshot` results in a huge delay as it grabs a current snapshot... which really does not seem like the right use case here.

*** subsequent review show that /img has the current image if we have found one on disk (and is blank otherwise), whereas /thumb seems to always point to a path that might just be a broken image? Hmmm..

@IDisposable
Copy link
Author

IDisposable commented Jan 25, 2025

At worst, we can massage camera.hls_url to replace the :8888/ with :5000/ and it should be correct, but would rather have a better config-driven source for this base URL for the images. Is something like replace(url,':8888/', ':5000/') available in the context of the execution of the template? Looks like this is flask templating, so we could likely pass more config information at the render call like so (borrowing the logic from web_ui.py logic here)

    @app.route("/cams.m3u8")
    @auth_required
    def iptv_playlist():
        """
        Generate an m3u8 playlist with all enabled cameras.
        """
        cameras = web_ui.format_streams(wb.streams.get_all_cam_info())
        hostname = env_bool("DOMAIN", urlparse(request.root_url).hostname or "localhost")
        resp = make_response(render_template("m3u8.html", cameras=cameras, hostname=hostname))
        resp.headers.set("content-type", "application/x-mpegURL")
        return resp

Also, could technically use camera.thumbnail but that points to the AWS-cached images and thus is dependent on the Wyze infrastructure being up and those URLs probably are not signed for a very long access time, so would likely break the guide. NOT RECOMMENDED

@IDisposable
Copy link
Author

We could insert a line (at line 141) in the format_stream method to precompute the public-passthrough base address thus:

    "web_ui" : (config.WEB_UI or f"http://{hostname}:5000"),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant