johnvuko / flutter_cast

Dart package to discover and connect with Chromecast devices
MIT License
46 stars 38 forks source link

Play, pause and volume message #28

Open salamay opened 2 years ago

salamay commented 2 years ago

Please, i have searched on how to play, pause and stop chromecast but none is working, what is the right message to send in json format to play, pause and stop

kayosilva commented 1 year ago

I'm having the same problem, I've searched everywhere how to send the play/pause event to chromecast and I didn't find it. I've already tried to send the connect event with the "autoPlay":false attribute, but that doesn't work either.

JoseBarreto1 commented 1 year ago

I also have that problem

Tiagocf2 commented 1 year ago

I found this link on issue #22 about the messages: https://developers.google.com/cast/docs/media/messages#Play

Also check: https://github.com/jonathantribouharet/flutter_cast/issues/8#issuecomment-1001748664

Tiagocf2 commented 1 year ago

I only managed to make the PLAY and PAUSE message work though, for some reason my VOLUME message is not being accepted...

My message ```dart session.sendMessage( CastSession.kNamespaceMedia, { 'type': 'VOLUME', 'volume': {'muted': true}, 'mediaSessionId': 1, } ); ```
Response message ```dart {requestId: 107, type: INVALID_REQUEST, reason: INVALID_COMMAND} ```
JoseBarreto1 commented 1 year ago

I ended up looking at the google documentation:

https://developers.google.com/cast/docs/media/messages#Play

session.sendMessage(
  CastSession.kNamespaceMedia, {
    'type': 'PLAY', // 'PAUSE'
    'requestId':  requestID,
    'mediaSessionId': mediaSessionID,
  }
);
kayosilva commented 1 year ago

Based on the information @JoseBarreto1 provided.

When you connect to chromecast you will get the event response and you will be able to get the requestID.

After the message with the media data you sent to chromecast, you will also receive a media playback status event, at which time you will be able to get the mediaSessionId.

These two attributes will be useful to send an event to control SEEK, PLAY/PAUSE to chromecast. In the example implementation of the plugin page https://pub.dev/packages/cast/example I made some changes to achieve it, as follows:

// ...
class _MyHomePageState extends State<MyHomePage> {
  Future<List<CastDevice>>? _future;
  late dynamic requestId;
  late dynamic mediaSessionId;
  late CastSession session;

@override
  void initState() {
// ...

Future<void> _connectAndPlayMedia(BuildContext context, CastDevice object) async {
    session = await CastSessionManager().startSession(object);

// ...
    var index = 0;
    session.messageStream.listen((message) {
       index += 1;

       if (index == 2) {
         Future.delayed(Duration(seconds: 5)).then((x) {
            requestId = message['requestId'];
            _sendMessagePlayVideo(session);
         });
       }

       if (message['status'] != null && message['status'][0] != null && message['status'][0]['playerState'] == 'PLAYING') {
            mediaSessionId = message['status'][0]['mediaSessionId'];
       }
    });

//...   

}

// ...

pause() {
    Map<String, dynamic> action = {
      'type': 'PAUSE',
      'mediaSessionId': mediaSessionId,
      'requestId': requestId
    };
    this.isPlaying = false;
    session.sendMessage(CastSession.kNamespaceMedia, action);
  }

  play() {
    Map<String, dynamic> action = {
      'type': 'PLAY',
      'mediaSessionId': mediaSessionId,
      'requestId': requestId
    };
    this.isPlaying = true;
    session.sendMessage(CastSession.kNamespaceMedia, action);
  }

  seek(seconds) {
    Map<String, dynamic> action = {
      'type': 'SEEK',
      'mediaSessionId': mediaSessionId,
      'requestId': requestId,
      'currentTime': seconds
    };
    session.sendMessage(CastSession.kNamespaceMedia, action);
  }

// ...
guyluz11 commented 10 months ago

Hey all. It looks like there is a couple of issues about people not sure how to use features or asking if the feature exists and this (in my opinion) underlines a problem with the package and code.

First of all, we should

  1. create an enum for 'type' for clear code (maybe with the option of passing a string if needed).
  2. Easy functions for play, pause, volume...
  3. And update the documentation to be more precise and contain links to pub.dev page, link Google documentation of casting as described in other issue #22 .

It looks like the repo maintainer is active and accepting PR so this package is not dead just need some love from us the pakacge users.

I suggest that if we find something good that would be useful like how to "send the play/pause event" we will create a PR to add this functionality to everyone.

I have started with 2 PRs of adding Linux\Windows support and updating the example project and will probably add more on the way.

So let's make this package better by helping each other with the knowledge we gained.

johnvuko commented 10 months ago

Hello, no enum is needed as each code / action is specific to the application, this package is not dedicated to Youtube. However if you find the code to work with Youtube it could be added in the documentation as an example. Last time I've check (2 years ago), it was not easy to work with Youtube.

guyluz11 commented 9 months ago

Hello, no enum is needed as each code / action is specific to the application, this package is not dedicated to Youtube. However if you find the code to work with Youtube it could be added in the documentation as an example. Last time I've check (2 years ago), it was not easy to work with Youtube.

What about general settings like volume related (up down mute...), open links (browser), shut down/wake up, navigation forward and backward..., remote control buttons, cursor pointer, writing (keyboard), displaying messages on the screen, reading text out loud?

I think creating an easy API for developers for the general options that Chromecast can do is important and will be a big upgrade.

johnvuko commented 9 months ago

Yes I'm ok with everything supported by the official SDK. Unfortunately the sender part (the one this lib used) is not open source and neither the cast protocol. This project is based on another lib https://github.com/dylanmckay/gcast/tree/master (this guy has read chromium cast part to do this).

guyluz11 commented 9 months ago

Created simple functions that can be called on the CastSession: Play/Pause (works only on YouTube), change volume (@Tiagocf2), Open Media (now with isolated call), getStatus function (to get current volume).

Added an example of opening PLEX, opening YouTube didn't work for me (stuck on the logo), and I can't find the appId of Netflix, also would be nice the one for Spotify. Added all of the functionality to the example app

image

This is on my repo but it will not work on iOS but does support Dart native because it is one or the other and I need Dart native more. Will revert back to the iOS support and create a PR after my previous PRs get accepted to reduce complications. Link for my fork if you want to test it out https://github.com/guyluz11/flutter_cast/tree/multicast_version

For API I have looked on This one for the available messages https://developers.google.com/cast/docs/reference/web_receiver/cast.framework.messages

And this one for the properties of each message https://developers.google.com/cast/docs/media/messages

Didn't check but I think it will be easier to use a project from JavaScript than Rust as a reference for the SDK https://github.com/xat/castnow

guyluz11 commented 9 months ago

Added function to open link in browser :D

And I have found a javascript package that manages to open YouTube videos https://github.com/i8beef/node-red-contrib-castv2/blob/master/lib/YouTubeController.js I have started working on that and managed to get YouTube loungeToken and ok status from the last request but it still missing something. Feel free to check it out, maybe you will see something that I have missed https://github.com/guyluz11/flutter_cast/blob/09e845de9b872cb734e725b09b89d64a8fc281b9/lib/device.dart#L89