-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3eb6ba9
Showing
12 changed files
with
225 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.DS_store | ||
out/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"recommendations": [ | ||
"rokucommunity.brightscript" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"type": "brightscript", | ||
"request": "launch", | ||
"name": "BrightScript Debug: Launch", | ||
"stopOnEntry": false, | ||
"host": "${promptForHost}", | ||
"password": "${promptForPassword}", | ||
"rootDir": "${workspaceFolder}", | ||
"files": [ | ||
"manifest", | ||
"source/**/*.*", | ||
"locale/**/*.*", | ||
"images/**/*.*" | ||
], | ||
"enableDebuggerAutoRecovery": false, | ||
"stopDebuggerOnAppExit": false | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2022 Marcelo Lv Cabral @lvcabral | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Roku Home Assistant Cast App | ||
|
||
Roku app to allow Home Assistant integration video stream cameras and other media to Roku devices. | ||
|
||
## How to Deploy the app to your Roku | ||
|
||
<img src="./locale/default/images/home-assistant-hd-icon.png" width="290" height="217" border="2" align="right" /> | ||
In order to side load an application on Roku you need to follow a few steps: | ||
|
||
1. Set up your Roku device to enable **Developer Settings** on your Roku device (Step 1 of [these instructions](https://developer.roku.com/en-gb/docs/developer-program/getting-started/developer-setup.md)) | ||
2. Create a zip file with the contents of this repository or download the zip from the [Releases](releases) page | ||
3. Access the **Development Application Installer** to upload and install the app package (Steps 2 and 3 of [these instructions](https://developer.roku.com/en-gb/docs/developer-program/getting-started/developer-setup.md)) | ||
|
||
A couple of notes: | ||
|
||
- If you run the app from Roku UI it will display a message: _"App started with no deep link, use HA Roku custom component to stream a camera or other media."_ this is normal, see the sections below to learn how to use the application with Home Assistant or directly stream content using an URL with `deep link`. | ||
- If you use VSCode, it's recommended to use the [_BrightScript Language Extension_](https://marketplace.visualstudio.com/items?itemName=RokuCommunity.brightscript) that allows you execute the steps 2 and 3 above just using VSCode's **Run** command. | ||
|
||
## How to show a Home Assistant camera on Roku | ||
|
||
Once you have the **Home Assistant Cast** app installed follow the steps below to have a camera streaming to your Roku: | ||
|
||
1. Install [**Custom Roku Media Player**](https://github.com/lvcabral/ha-roku-media-player) integration on you Home Assistance and restart it. | ||
1. Have your Roku device properly configured in Home Assistant with an Entity on `media_player` platform (e.g `media_player.roku_ultra`) | ||
1. Create an Automation with an action that calls the service `camera.play_stream` from one of your cameras to your Roku entity. | ||
|
||
Below is an example of an Automation that shows the front door Floodlight Camera on Roku when the motion sensor is triggered. | ||
|
||
```YAML | ||
alias: Stream Camera on Motion Detected | ||
description: '' | ||
trigger: | ||
- platform: state | ||
entity_id: binary_sensor.backyard_motion | ||
to: 'on' | ||
condition: [] | ||
action: | ||
- service: camera.play_stream | ||
target: | ||
entity_id: | ||
- camera.floodlight_camera | ||
data: | ||
media_player: media_player.roku_ultra | ||
format: hls | ||
mode: single | ||
``` | ||
## How to Manually Send a Stream to the Roku app | ||
If you want to test the app without the use of Home Assistant, you can use the command below in your terminal. | ||
Please note: | ||
- Make sure you replace the `IP address` below with the one your Roku device is using | ||
- The `contentId` parameter can contain any valid stream URL supported by Roku (hls, mp4, mkv,...) make sure you [encode it](https://www.urlencoder.io/) | ||
|
||
```zsh | ||
curl -d '' 'http://192.168.0.74:8060/launch/dev?contentId=https%3A%2F%2Fjell.yfish.us%2Fmedia%2Fjellyfish-30-mbps-hd-h264.mkv' | ||
``` | ||
|
||
## License | ||
|
||
Copyright (C) 2022 Marcelo Lv Cabral. All rights reserved. | ||
|
||
Licensed under [MIT](LICENSE) License. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
title=Home Assistant Cast | ||
major_version=1 | ||
minor_version=0 | ||
build_version=0 | ||
splash_min_time=3000 | ||
splash_color=#FFFFFFFF | ||
mm_icon_focus_fhd=pkg:/locale/default/images/home-assistant-fhd-icon.png | ||
mm_icon_focus_hd=pkg:/locale/default/images/home-assistant-hd-icon.png | ||
splash_screen_fhd=pkg:/locale/default/images/home-assistant-fhd-splash.png | ||
splash_screen_hd=pkg:/locale/default/images/home-assistant-hd-splash.png |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
' ****** | ||
' ****** Home Assistant Stream Channel | ||
' ****** | ||
Library "v30/bslCore.brs" | ||
|
||
function main(args) | ||
m.screen = createObject("roScreen", true) | ||
m.screen.setAlphaEnable(true) | ||
m.codes = bslUniversalControlEventCodes() | ||
m.port = createObject("roMessagePort") | ||
m.screen.setMessagePort(m.port) | ||
m.player = CreateObject("roVideoPlayer") | ||
m.player.SetMessagePort(m.port) | ||
if invalid <> args.contentId | ||
playStreaming(args.contentId) | ||
else | ||
drawBackground("App started with no deep link, use HA Roku custom component to stream a camera or other media.") | ||
end if | ||
streaming = false | ||
paused = false | ||
while true | ||
event = wait(0, m.port) | ||
if type(event) = "roUniversalControlEvent" | ||
button = event.getInt() | ||
if button = m.codes.button_play_pressed | ||
if not paused | ||
m.player.pause() | ||
else | ||
m.player.resume() | ||
end if | ||
else if button = m.codes.button_back_pressed | ||
if streaming | ||
m.player.stop() | ||
end if | ||
exit while | ||
end if | ||
else if type(event) = "roVideoPlayerEvent" | ||
if event.isStreamStarted() | ||
streaming = true | ||
else if event.isPaused() | ||
paused = true | ||
else if event.isResumed() | ||
paused = false | ||
else if event.isFullResult() or event.isRequestFailed() | ||
info = event.getInfo() | ||
if invalid <> info and invalid <> info.DebugMessage | ||
status = info.DebugMessage | ||
else | ||
status = event.getMessage() | ||
end if | ||
m.player.stop() | ||
streaming = false | ||
paused = false | ||
drawBackground(status) | ||
end if | ||
end if | ||
end while | ||
end function | ||
|
||
sub drawBackground(status = "") | ||
m.screen.Clear(0) | ||
m.screen.SwapBuffers() | ||
bmp = CreateObject("roBitmap", "pkg:/images/ha-background.png") | ||
width = bmp.getWidth() | ||
if width <> m.screen.getWidth() | ||
scale = m.screen.getWidth() / width | ||
m.screen.DrawScaledObject(0, 0, scale, scale, bmp) | ||
else | ||
m.screen.DrawObject(0, 0, bmp) | ||
end if | ||
color = &hFFFFFFFF | ||
font_registry = CreateObject("roFontRegistry") | ||
if "" <> status | ||
font = font_registry.GetDefaultFont(24, false, false) | ||
m.screen.drawText(status, 100, m.screen.getHeight()-100, color, font) | ||
end if | ||
if invalid <> m.streamUrl | ||
font = font_registry.GetDefaultFont(16, false, false) | ||
m.screen.drawText("ContentId: " + m.streamUrl, 100, m.screen.getHeight()-50, color, font) | ||
end if | ||
m.screen.SwapBuffers() | ||
end sub | ||
|
||
sub playStreaming(contentId) | ||
if invalid <> contentId | ||
m.streamUrl = contentId.decodeUri() | ||
content = { | ||
Stream: { url: m.streamUrl } | ||
} | ||
if m.streamUrl.right(5) = ".m3u8" | ||
content.StreamFormat = "hls" | ||
end if | ||
m.screen.Clear(0) | ||
m.screen.SwapBuffers() | ||
m.player.SetContentList([content]) | ||
m.player.play() | ||
end if | ||
end sub |