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

Initial code for google-cast client #2227

Merged
merged 21 commits into from
Mar 9, 2021
Merged

Conversation

slaff
Copy link
Contributor

@slaff slaff commented Feb 23, 2021

This library allows you to communicate with Chromecast dongles or smart TVs that support the Google Cast Protocol.

Copy link
Contributor

@mikee47 mikee47 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done a review and opened a PR on your repo.

The sample runs under Host for me OK, but I had to comment out some stuff in onMessage so guess that's still work in progress. I get {"type":"CLOSE"} response when I target my chromecast dongle, so guess it's doing something!

Perhaps the complexities of processing a message could be handled using a wrapper class which manages a contained extensions_api_cast_channel_CastMessage. Further, that could first be done for nanopb, with the pbEncodeData and pbDecodeData helpers integrated into a Protobuf::Stream class.

These classes could then deal with memory allocation, de-allocation, getting/setting data, etc. in a safer and more user-friendly way.

@mikee47
Copy link
Contributor

mikee47 commented Feb 27, 2021

Also, it would probably be easier working with this in a separate library? i.e. submodule

@slaff
Copy link
Contributor Author

slaff commented Feb 28, 2021

Also, it would probably be easier working with this in a separate library? i.e. submodule

Yes, once this is at least working with the basic sample I will move it to a submodule as DIAL and others.

@mikee47
Copy link
Contributor

mikee47 commented Feb 28, 2021

@slaff
Copy link
Contributor Author

slaff commented Feb 28, 2021

@mikee47 Let's merge your improvements. First can you create a PR with the protobuf/nanopb improvements in SmingHub. After that I will rebase on develop and you can create a PR against slaff/Sming with the further improvements to the code.

I get {"type":"CLOSE"} response when I target my chromecast dongle, so guess it's doing something!

Do you have an idea which google cast version is your dongle using? It seems to me like it is just rejecting the connection due to wrong protocol.

Found another useful reference source https://github.com/home-assistant-libs/pychromecast/tree/master/pychromecast

We can add this also to the documentation.

@mikee47
Copy link
Contributor

mikee47 commented Feb 28, 2021

@mikee47 Let's merge your improvements. First can you create a PR with the protobuf/nanopb improvements in SmingHub. After that I will rebase on develop and you can create a PR against slaff/Sming with the further improvements to the code.

OK.

I get {"type":"CLOSE"} response when I target my chromecast dongle, so guess it's doing something!

I've discovered this is a standard response to an error condition. Sending the request immediately after a Connect doesn't work. However, sending the launch request when a PONG is received works fine.

@mikee47
Copy link
Contributor

mikee47 commented Mar 1, 2021

Re. device discovery we could use UPnP for that... DIAL stuff

@slaff
Copy link
Contributor Author

slaff commented Mar 1, 2021

Re. device discovery we could use UPnP for that... DIAL stuff

Hm... The last time I was looking at the docs they were saying that Google Cast Protocol v2 uses mdns to find the devices. Do you mean that all Google Cast devices support also UPnP so that we can use this instead?

@mikee47
Copy link
Contributor

mikee47 commented Mar 1, 2021

Yes, it's probably not standard and MDNS is going to be more efficient. Currently the MDNS component doesn support discovery, that does need adding. All the chromecast-capable devices I have (several) are reported via UPnP with <deviceType>urn:dial-multiscreen-org:device:dial:1</deviceType>, so it would at least allow the device to be specified by friendly name.

@slaff slaff force-pushed the feature/google-cast branch from 3fc8e27 to 0b31086 Compare March 1, 2021 11:04
@slaff
Copy link
Contributor Author

slaff commented Mar 1, 2021

Currently the MDNS component doesn support discovery, that does need adding.

Some time ago I have started work on this but never tested it and it's still raw. But feel free to use it and enhance it.

develop...slaff:feature/mdns-query

@slaff
Copy link
Contributor Author

slaff commented Mar 1, 2021

After that I will rebase on develop and you can create a PR against

@mikee47 This PR is rebased on latest develop. Your changes from feature/channel-cast are also merged. You can now get the latest version of this PR/branch and add the rest on top of it.

@mikee47
Copy link
Contributor

mikee47 commented Mar 1, 2021

@slaff Have pushed to your repo, got it playing back a video using the media URL from the pychromecast video2 example.

I'm getting more accustomed to how all this fits together. The library https://github.com/jhenstridge/cast-app is interesting as it goes a step further to define a channel as the source/destination pair, then within that channel interfaces which correspond to the particular namespace. Only when the TCP connection has been established to the Chromecast device is a channel created, with the default Connection and Hearbeat interfaces. The Media interfaces is constructed only when requested.

However, it's not clear to me yet whether this is entirely necessary as AFAIK only one application can be active at a time, hence only one interface of any given type. Something to chew on I think.

@slaff
Copy link
Contributor Author

slaff commented Mar 2, 2021

got it playing back a video using the media URL from the pychromecast video2 example.

Awesome, thanks! Will test it tonight with my TV.

@mikee47
Copy link
Contributor

mikee47 commented Mar 2, 2021

@slaff Thanks for the MDNS code, just whipping it into shape so expect PR shortly.

@slaff slaff force-pushed the feature/google-cast branch from 4a86e5d to 5e818b4 Compare March 2, 2021 09:42
@slaff slaff added this to the 4.3.0 milestone Mar 4, 2021
@slaff slaff mentioned this pull request Mar 4, 2021
5 tasks
@mikee47 mikee47 force-pushed the feature/google-cast branch from 5e818b4 to 8a26854 Compare March 8, 2021 07:24
@mikee47
Copy link
Contributor

mikee47 commented Mar 8, 2021

@slaff Taken the liberty of rebasing, added a PR to your repo. proposing client discovery

@slaff slaff changed the title [WIP] Initial code for google-cast client Initial code for google-cast client Mar 8, 2021
@mikee47
Copy link
Contributor

mikee47 commented Mar 8, 2021

Note that ESP32 will require #2248.

slav-at-attachix and others added 7 commits March 8, 2021 13:17
Redefine ChannelType as strong enum
Place `toString(ChannelType)` in global namespace
Use `nullptr` for `sourceId` and `destinationId` parameters in `generateMessage` to indicate "use default values"
Fix casting
Make `newInputStream` a helper function with more generic `IDataSourceStream` argument. Use `readBytes` instead of `readDataBlock` + `seek`
Use flash strings where appropriate
Add `String&` overload for `generateMessage`
Fix signed/unsigned comparisons
Use htonl/ntohl instead of manually coding byte ordering
Revise `Client::play` using only one json document
Also doesn't seem to work with Axtls (get error -112)
mikee47 and others added 13 commits March 8, 2021 13:17
Stream data directly to TcpClient rather than using intermediate buffering
For receiving data, use LimitedMemoryStream with single allocation when size is known
If entire message is obtained in initial buffer then use it directly (no copy)
Channel provides nameSpace via virtual method, remove enum
Replace `publish` and `sendMessage` with `send`
@slaff slaff force-pushed the feature/google-cast branch from 9deaf16 to b2adccf Compare March 8, 2021 12:54
@slaff
Copy link
Contributor Author

slaff commented Mar 8, 2021

@mikee47 When you have time compile the latest version from this PR and check if it is working on your multiple Google Cast v2 devices.

@slaff slaff force-pushed the feature/google-cast branch from b2adccf to ff082c4 Compare March 8, 2021 13:05
@mikee47
Copy link
Contributor

mikee47 commented Mar 8, 2021

@slaff Yep, works a treat. Tested against a Chromecast dongle and a Sony SRS-HG1 speaker, sample running on ESP8266 nodeMCU and ESP32 wroom32. Sample could probably do with some polishing; for example, switching playback to a different device doesn't work (requires a reset) but does the job fine :-)

@slaff
Copy link
Contributor Author

slaff commented Mar 8, 2021

and ESP32 wroom32

Wow!

switching playback to a different device doesn't work (requires a reset) but does the job fine :-)

This can be part of another PR.

@mikee47 Thanks again for your work and testing!

@mikee47
Copy link
Contributor

mikee47 commented Mar 8, 2021

I'm particularly interested in chrome/googlecast because it's (relatively) open and well supported. One of my plans for Sming is a remote controller for chromecast/DLNA devices with physical buttons, volume control, etc. Touch screens are all very well but they can be a real PITA sometimes. This and the UPnP stuff will all be essential for that!

NB. The ESP32-S2 also looks very promising as if we can get the host USB stuff working I can plug it into my ODAC :-)

@slaff slaff merged commit 89ee6c7 into SmingHub:develop Mar 9, 2021
@slaff
Copy link
Contributor Author

slaff commented Mar 9, 2021

@mikee47 How about adding also your audio stuff https://github.com/mikee47/SmingAudio as a separate library to Sming?
Also what is the state of the Json Streaming Parser: https://github.com/mikee47/JsonStreamingParser/tree/develop ? Shall we merge it too?

@mikee47
Copy link
Contributor

mikee47 commented Mar 9, 2021

@slaff I'll review both of those, will need a bit more work before I'm happy to submit them. The MP3 stuff is a bit of a gimmick on the ESP8266 (not enough RAM or processing power) but the sort of thing the ESP32 excels at; it'll need I2S support though so bit of work to be done there.

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

Successfully merging this pull request may close these issues.

3 participants