thibauts / node-castv2-client

A Chromecast client based on the new (CASTV2) protocol
MIT License
646 stars 92 forks source link

Add support for queues #62

Closed angelnu closed 7 years ago

angelnu commented 7 years ago

Hi,

Based on #38 I added support for queues to the default media player. I tested it with audio files and it works fine (see example exploiter bellow).

I noticed a positive side effect even for single URLs: it is possible to update the metadata in the middle of the play without having to reload (=interrupt) it.

I found additional parameters for the messages by looking at the receiver event data which is documented here: https://developers.google.com/cast/docs/reference/receiver/cast.receiver.MediaManager.QueueUpdateRequestData

Thanks to @jeffdagala and @thibauts !

    var Client                = require('castv2-client').Client;
    var DefaultMediaReceiver  = require('castv2-client').DefaultMediaReceiver;
    var util                  = require("util");

    function connectToDevice(host) {

      var client = new Client();

      client.connect(host, function() {
        console.log('connected, launching app ...');

        client.launch(DefaultMediaReceiver, function(err, player) {

          var mediaList = [
            {
              autoplay : true,
              preloadTime : 3,
              startTime : 1,
              activeTrackIds : [],
              playbackDuration: 4,
              media: {
                contentId: "http://192.168.2.3:80/musica/Metal/Linkin%20Park/Linkin%20Park%20-%20A%20Thousand%20Suns%20ak6103/06%20Robot%20Boy.mp3",
                contentType: "audio/mpeg",
                streamType: 'BUFFERED'
              }
            },
            {
              autoplay : true,
              preloadTime : 3,
              startTime : 2,
              activeTrackIds : [],
              playbackDuration: 4,
              media: {
                contentId: "http://192.168.2.3:80/musica/Metal/Linkin%20Park/Linkin%20Park%20-%20A%20Thousand%20Suns%20ak6103/02%20The%20Radiance%20(featuring%20an%20interview%20portion%20of%20J.%20Robert%20Oppenheimer).mp3",
                contentType: "audio/mpeg",
                streamType: 'BUFFERED'
              }
            },
            {
              autoplay : true,
              preloadTime : 3,
              startTime : 3,
              activeTrackIds : [],
              playbackDuration: 4,
              media: {
                contentId: "http://192.168.2.3:80/musica/Metal/Linkin%20Park/Linkin%20Park%20-%20A%20Thousand%20Suns%20ak6103/03%20Burning%20in%20the%20Skies.mp3",
                contentType: "audio/mpeg",
                streamType: 'BUFFERED'
              }
            }
          ];

          console.log('app "%s" launched, loading medias...', player.session.displayName);

          player.on('status', function(status) {
            console.log('status broadcast = %s', util.inspect(status)," ");
          });

          // loads multiple items
          player.queueLoad(mediaList, {startIndex:1, repeatMode: "REPEAT_OFF"}, function(err, status) {
             console.log("Loaded QUEUE: " + util.inspect(err) + util.inspect(status));
             player.queueInsert([{
                                  autoplay : true,
                                  preloadTime : 4,
                                  startTime : 8,
                                  activeTrackIds : [],
                                  playbackDuration: 4,
                                  media: {
                                    contentId: "http://192.168.2.3:80/musica/Metal/Linkin%20Park/Linkin%20Park%20-%20A%20Thousand%20Suns%20ak6103/12%20Iridescent.mp3",
                                    contentType: "audio/mpeg",
                                    streamType: 'BUFFERED',
                                    metadata: {metadataType:3, title:"Original title"}
                                }}],
                                function(err, status) {
                  console.log("Inserted in QUEUE: " + util.inspect(err) + util.inspect(status));
                  player.queueRemove([2],{currentItemId:0}, function(err, status) {
                    console.log("Removed from QUEUE: " + util.inspect(err) + util.inspect(status));
                    player.queueUpdate([{itemId: 4,
                                         autoplay : true,
                                         preloadTime : 4,
                                         startTime : 60,
                                         activeTrackIds : [],
                                         playbackDuration: 4,
                                         media: {
                                           contentId: "http://192.168.2.3:80/musica/Metal/Linkin%20Park/Linkin%20Park%20-%20A%20Thousand%20Suns%20ak6103/12%20Iridescent.mp3",
                                           contentType: "audio/mpeg",
                                           streamType: 'BUFFERED',
                                           metadata: {metadataType:3, title:"Modifed title"}
                                       }}],
                                       {currentItemId:4},
                                       function(err, status) {
                      console.log("Updated Item: " + util.inspect(err) + util.inspect(status));
                      player.queueReorder([4,3,1], {currentItemId:4}, function(err, status) {
                        console.log("Reordered QUEUE: " + util.inspect(err) + util.inspect(status));
                      });
                    });
                  });
              });
          })

        });

      });

      client.on('error', function(err) {
        console.log('Error: %s', err.message);
        client.close();
      });

    }

    connectToDevice("192.168.2.39");
thibauts commented 7 years ago

This is awesome ! The code looks sensible and clean to me, the style is consistent, what could one ask for ? :)

Oh yeah, you could reindent a few data structures as commented in the commit, and add your name to contributors in the README ;)

angelnu commented 7 years ago

I am glad that you take my contribution :-)

I did not see any comments in the commit but I think I fixed all the inconsistent aliments.

If you could please publish a new version to npm I would appreciate - this way I can release an update to my exploiter package to make use of the official version. Thanks.

I could rework the example code I used to test and make it work as generic testcase using example mp3 hosted by google. I would then open a different issue for it.

thibauts commented 7 years ago

Could be useful as a wiki linked from the readme. I'll publish asap

angelnu commented 7 years ago

I added the example as testcase: it can either be executed directly with npm examples/queue.js or with npm test

I will do an extra pull request for it so that it can be reviewed separately from the main code in this request. Being the first testcase I write in javascript it might require changes.

thibauts commented 7 years ago

Merged and published as 1.2.0 (minor upped)