Beispiel #1
0
        /// <summary>
        /// Set mute state.
        /// </summary>
        /// <param name="mute">True to mute, False to unmute.</param>
        /// <returns></returns>
        /// <remarks>
        /// Returns True if call is successful, otherwise False.
        /// </remarks>
        public static async Task <(bool Succeeded, bool Result)> SetMute(
            bool mute
            )
        {
            var request = JsonRpcFactory.CreateRequest(
                Mixer.MethodSetMute,
                new
            {
                mute
            }
                );

            var response = await Mixer._query.Exec(request);

            if (response.Error != null)
            {
                return(false, false);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JValue.FromObject(response.Result).ToObject <bool>();

            return(true, result);
        }
Beispiel #2
0
        public void TestSerializingDepositWithoutValidation()
        {
            var serializer = new Serializer();
            var factory    = new JsonRpcFactory();

            var jsonRpc = factory.Create(new DepositRequestData
            {
                Username        = "******",
                Password        = "******",
                NotificationURL = "URL_to_your_notification_service",
                EndUserID       = "12345",
                MessageID       = "your_unique_deposit_id",
                Attributes      = new DepositRequestDataAttributes
                {
                    Locale      = "sv_SE",
                    Currency    = "SEK",
                    IP          = "123.123.123.123",
                    MobilePhone = "+46709876543",
                    Firstname   = "John",
                    Lastname    = "Doe",
                    NationalIdentificationNumber = "790131-1234"
                }
            }, "Deposit");

            var serialized = serializer.SerializeData(jsonRpc.Params.Data);
            var expected   = "AttributesCurrencySEKFirstnameJohnIP123.123.123.123LastnameDoeLocalesv_SEMobilePhone+46709876543NationalIdentificationNumber790131-1234EndUserID12345MessageIDyour_unique_deposit_idNotificationURLURL_to_your_notification_servicePasswordmerchant_passwordUsernamemerchant_username";

            Assert.AreEqual(expected, serialized);
        }
Beispiel #3
0
        /// <summary>
        /// Search the library for tracks where field contains values.
        /// </summary>
        /// <param name="query">one or more queries to search for</param>
        /// <param name="uris">zero or more URI roots to limit the search to</param>
        /// <param name="exact">if the search should use exact matching</param>
        /// <returns></returns>
        /// <remarks>
        /// field can be one of uri, track_name, album, artist, albumartist, composer,
        /// performer, track_no, genre, date, comment, or any.
        /// If uris is given, the search is limited to results from within the URI roots.
        /// For example passing uris=['file:'] will limit the search to the local backend.
        /// </remarks>
        public static async Task <(bool Succeeded, SearchResult[] Result)> Search(
            Query query,
            string[] uris = null,
            bool exact    = false
            )
        {
            var request = JsonRpcFactory.CreateRequest(
                Library.MethodSearch,
                new
            {
                query = query?.Format(),
                uris,
                exact
            }
                );

            var response = await Library._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JArray.FromObject(response.Result).ToObject <SearchResult[]>();

            return(true, result);
        }
Beispiel #4
0
        public async Task <Dictionary <string, Image> > GetImages(string[] uris)
        {
            var request = JsonRpcFactory.CreateRequest(Library.MethodGetImages, new ArgsUris()
            {
                Uris = uris
            });

            var response = await this._query.Exec(request);

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var imageDictionary = JObject.FromObject(response.Result).ToObject <Dictionary <string, List <Image> > >();

            var result = new Dictionary <string, Image>();

            if (imageDictionary == null)
            {
                return(result);
            }

            foreach (var pair in imageDictionary)
            {
                if (pair.Value == null || pair.Value.Count() <= 0)
                {
                    continue;
                }
                result.Add(pair.Key, pair.Value.First());
            }

            return(result);
        }
Beispiel #5
0
        /// <summary>
        /// Delete playlist identified by the URI.
        /// </summary>
        /// <param name="uri">URI of the playlist to delete</param>
        /// <returns></returns>
        /// <remarks>
        /// If the URI doesn’t match the URI schemes handled by the current backends,
        /// nothing happens.
        ///
        /// Returns True if deleted, False otherwise.
        /// </remarks>
        public static async Task <(bool Succeeded, bool Result)> Delete(
            string uri
            )
        {
            var request = JsonRpcFactory.CreateRequest(
                Playlists.MethodDelete,
                new
            {
                uri
            }
                );

            var response = await Playlists._query.Exec(request);

            if (response.Error != null)
            {
                return(false, false);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JValue.FromObject(response.Result).ToObject <bool>();

            return(true, result);
        }
Beispiel #6
0
        /// <summary>
        /// Lookup the images for the given URIs
        /// </summary>
        /// <param name="uris">list of URIs to find images for</param>
        /// <returns></returns>
        /// <remarks>
        /// Backends can use this to return image URIs for any URI they know
        /// about be it tracks, albums, playlists.
        /// The lookup result is a dictionary mapping the provided URIs to lists of images.
        /// Unknown URIs or URIs the corresponding backend couldn’t find anything
        /// for will simply return an empty list for that URI.
        /// </remarks>
        public static async Task <(bool Succeeded, Dictionary <string, Image[]> Result)> GetImages(
            string[] uris
            )
        {
            var request = JsonRpcFactory.CreateRequest(
                Library.MethodGetImages,
                new
            {
                uris
            }
                );

            var response = await Library._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JObject.FromObject(response.Result)
                         .ToObject <Dictionary <string, Image[]> >();

            return(true, result);
        }
Beispiel #7
0
        /// <summary>
        /// Create a new playlist.
        /// </summary>
        /// <param name="name">name of the new playlist</param>
        /// <param name="uriScheme">use the backend matching the URI scheme</param>
        /// <returns></returns>
        /// <remarks>
        /// </remarks>
        public static async Task <(bool Succeeded, Playlist Result)> Create(
            string name,
            string uriScheme = null
            )
        {
            var request = JsonRpcFactory.CreateRequest(
                Playlists.MethodCreate,
                new
            {
                name,
                uri_scheme = uriScheme
            }
                );

            var response = await Playlists._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = (response.Result == null)
                ? null
                : JObject.FromObject(response.Result).ToObject <Playlist>();

            return(true, result);
        }
Beispiel #8
0
        /// <summary>
        /// Add tracks to the tracklist.
        /// </summary>
        /// <param name="uris">list of URIs for tracks to add</param>
        /// <param name="atPosition">position in tracklist to add tracks</param>
        /// <returns></returns>
        /// <remarks>
        /// If uris is given instead of tracks, the URIs are looked up in the library
        /// and the resulting tracks are added to the tracklist.
        /// If at_position is given, the tracks are inserted at the given position
        /// in the tracklist.If at_position is not given,
        /// the tracks are appended to the end of the tracklist.
        /// </remarks>
        public static async Task <(bool Succeeded, TlTrack[] Result)> Add(
            string[] uris,
            int?atPosition = null
            )
        {
            var request = JsonRpcFactory.CreateRequest(
                Tracklist.MethodAdd,
                new
            {
                at_position = atPosition,
                uris
            }
                );

            var response = await Tracklist._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JArray.FromObject(response.Result).ToObject <TlTrack[]>();

            return(true, result);
        }
Beispiel #9
0
        /// <summary>
        /// The position of the given track in the tracklist.
        /// </summary>
        /// <param name="tlId">TLID of the track to find the index of</param>
        /// <returns></returns>
        /// <remarks>
        /// ** Argument tl_track is not works **
        ///
        /// If neither tl_track or tlid is given we return the index of
        /// the currently playing track.
        /// </remarks>
        public static async Task <(bool Succeeded, int?Result)> Index(
            int tlId
            )
        {
            var request = JsonRpcFactory.CreateRequest(
                Tracklist.MethodIndex,
                new
            {
                tlid = tlId
            }
                );

            var response = await Tracklist._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JValue.FromObject(response.Result).ToObject <int?>();

            return(true, result);
        }
Beispiel #10
0
        /// <summary>
        /// Returns a slice of the tracklist, limited by the given start and end positions.
        /// </summary>
        /// <param name="start">position of first track to include in slice</param>
        /// <param name="end">position after last track to include in slice ** end track is not target! **</param>
        /// <returns></returns>
        public static async Task <(bool Succeeded, TlTrack[] Result)> Slice(
            int start,
            int end
            )
        {
            var request = JsonRpcFactory.CreateRequest(
                Tracklist.MethodSlice,
                new
            {
                start,
                end
            }
                );

            var response = await Tracklist._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JArray.FromObject(response.Result).ToObject <TlTrack[]>();

            return(true, result);
        }
        public void TestSerializingDeposit()
        {
            var factory      = new JsonRpcFactory();
            var testAssembly = typeof(JsonRpcSignerTest).Assembly;

            TrustlyApiClientSettings settings;

            using (var merchantPrivateKey = testAssembly.GetManifestResourceStream("Trustly.Api.Client.UnitTests.Keys.merchant_private_key.cer"))
            {
                using (var merchantPublicKey = testAssembly.GetManifestResourceStream("Trustly.Api.Client.UnitTests.Keys.merchant_public_key.cer"))
                {
                    settings = TrustlyApiClientSettings
                               .ForTest()
                               .WithCredentialsFromEnv()
                               .WithCertificatesFromStreams(merchantPublicKey, merchantPrivateKey)
                               .AndTrustlyCertificate();
                }
            }

            var requestData = new DepositRequestData
            {
                NotificationURL = "localhost:1000",
                MessageID       = "82bdbc09-7605-4265-b416-1e9549397edd",
                EndUserID       = "127.0.0.1",

                Username = "******",
                Password = "******", // Is not the real password

                Attributes = new DepositRequestDataAttributes
                {
                    Amount    = "100.00",
                    Currency  = "SEK",
                    Country   = "SE",
                    Firstname = "John",
                    Lastname  = "Doe",
                }
            };

            var jsonRpcRequest = factory.Create(requestData, "Deposit", "258a2184-2842-b485-25ca-293525152425");

            var serializer = new Serializer();

            var serialized         = serializer.SerializeData(jsonRpcRequest.Params.Data);
            var expectedSerialized = "AttributesAmount100.00CountrySECurrencySEKFirstnameJohnLastnameDoeEndUserID127.0.0.1MessageID82bdbc09-7605-4265-b416-1e9549397eddNotificationURLlocalhost:1000Passworda6e404c9-7ca8-1204-863d-5642e27c2747Usernameteam_ceres";

            Assert.AreEqual(expectedSerialized, serialized);

            var signer = new JsonRpcSigner(serializer, settings);

            var plaintext         = signer.CreatePlaintext(serialized, jsonRpcRequest.Method, jsonRpcRequest.Params.UUID);
            var expectedPlaintext = "Deposit258a2184-2842-b485-25ca-293525152425AttributesAmount100.00CountrySECurrencySEKFirstnameJohnLastnameDoeEndUserID127.0.0.1MessageID82bdbc09-7605-4265-b416-1e9549397eddNotificationURLlocalhost:1000Passworda6e404c9-7ca8-1204-863d-5642e27c2747Usernameteam_ceres";

            Assert.AreEqual(expectedPlaintext, plaintext);

            signer.Sign(jsonRpcRequest);

            var expectedSignature = "xRed4cLfZs2L5WoJVHiRFvD9yTTvbT0i/BgfhitnTvX7DpfmAz9cmGs3wcTpfYanGlW6hkY7zg7esuaGjPr3NvsWxLGLKBxw97oS7KDmp/FFPnrYulle4MsmKFH5jPB1HMZn2kybXO7a/v1QhVkyKgPGtGSznMBmR8iObbkBGjKbaHdpzwUR2HBK0bomwjIdG7Qx25UMTkMU8a9iNpvwXI71zO9/97DQJK3UiXCicJLNReOTtqcxWL/gUi9h/H7tK6M5kDeNtyRolOhznVZLX/rkFg7exhRvjPk8nEGjMJ3B1O4nEm/xFM0fh4uqfv8QyZrYEzX/K7cfNXflax4n0g==";

            Assert.AreEqual(expectedSignature, jsonRpcRequest.Params.Signature);
        }
Beispiel #12
0
        public void TestMissingDepositShopperStatement()
        {
            var serializer = new Serializer();
            var factory    = new JsonRpcFactory();
            var validator  = new JsonRpcValidator();

            var jsonRpc = factory.Create(new DepositRequestData
            {
                Username        = "******",
                Password        = "******",
                NotificationURL = "URL_to_your_notification_service",
                EndUserID       = "12345",
                MessageID       = "your_unique_deposit_id",
                Attributes      = new DepositRequestDataAttributes
                {
                    Country     = "SE",
                    Locale      = "sv_SE",
                    Currency    = "SEK",
                    IP          = "123.123.123.123",
                    MobilePhone = "+46709876543",
                    Firstname   = "John",
                    Lastname    = "Doe",
                    NationalIdentificationNumber = "790131-1234"
                }
            }, "Deposit");

            Assert.Throws <TrustlyDataException>(() =>
            {
                validator.Validate(jsonRpc);
            });

            jsonRpc.Params.Data.Attributes.ShopperStatement = "A Statement";

            validator.Validate(jsonRpc);
        }
Beispiel #13
0
        public async Task <bool> Stop()
        {
            var notice = JsonRpcFactory.CreateNotice(Playback.MethodStop);

            var response = await this._query.Exec(notice);

            return(true);
        }
Beispiel #14
0
        public async Task <bool> Clear()
        {
            var request = JsonRpcFactory.CreateRequest(Tracklist.MethodClear);

            var response = await this._query.Exec(request);

            return(true);
        }
Beispiel #15
0
        public async Task <bool> Play(int tlId)
        {
            var notice = JsonRpcFactory.CreateNotice(Playback.MethodPlay, new ArgsTlId()
            {
                TlId = tlId
            });

            var response = await this._query.Exec(notice);

            return(true);
        }
Beispiel #16
0
        public async Task <TlTrack> GetCurrentTlTrack()
        {
            var request = JsonRpcFactory.CreateRequest(Playback.MethodGetCurrentTlTrack);

            var response = await this._query.Exec(request);

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            return((response.Result == null)
                ? null
                : JObject.FromObject(response.Result).ToObject <TlTrack>());
        }
Beispiel #17
0
        public async Task <string> GetState()
        {
            var request = JsonRpcFactory.CreateRequest(Playback.MethodGetState);

            var response = await this._query.Exec(request);

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JValue.FromObject(response.Result).ToObject <string>();

            return(result);
        }
Beispiel #18
0
        public async Task <List <TlTrack> > GetTlTracks()
        {
            var request = JsonRpcFactory.CreateRequest(Tracklist.MethodGetTlTracks);

            var response = await this._query.Exec(request);

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JArray.FromObject(response.Result).ToObject <List <TlTrack> >();

            return(result);
        }
Beispiel #19
0
        /// <summary>
        /// If paused, resume playing the current track.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// Need to wait a little bit until get the correct return value of GetState.
        /// </remarks>
        public static async Task <bool> Resume()
        {
            var notice = JsonRpcFactory.CreateNotice(Playback.MethodResume);

            var response = await Playback._query.Exec(notice);

            if (response.Error != null)
            {
                return(false);
            }

            return(true);
        }
Beispiel #20
0
        /// <summary>
        /// Clear the tracklist.
        /// </summary>
        /// <returns></returns>
        public static async Task <bool> Clear()
        {
            var request = JsonRpcFactory.CreateRequest(Tracklist.MethodClear);

            var response = await Tracklist._query.Exec(request);

            if (response.Error != null)
            {
                return(false);
            }

            return(true);
        }
Beispiel #21
0
        /// <summary>
        /// Save the playlist.
        /// </summary>
        /// <param name="playlist"></param>
        /// <returns></returns>
        /// <remarks>
        /// For a playlist to be saveable, it must have the uri attribute set.
        /// You must not set the uri atribute yourself, but use playlist objects
        /// returned by create() or retrieved from playlists, which will always give you
        /// saveable playlists.
        ///
        /// The method returns the saved playlist.
        /// The return playlist may differ from the saved playlist.
        /// E.g. if the playlist name was changed, the returned playlist may have
        /// a different URI.
        /// The caller of this method must throw away the playlist sent to this method,
        /// and use the returned playlist instead.
        ///
        /// If the playlist’s URI isn’t set or doesn’t match the URI scheme
        /// of a current backend, nothing is done and None is returned.
        /// </remarks>
        public static async Task <(bool Succeeded, Playlist Result)> Save(
            Playlist playlist
            )
        {
            if (playlist == null)
            {
                return(false, null);
            }

            var args = new PlaylistArg()
            {
                Uri  = playlist.Uri,
                Name = playlist.Name
            };

            if (playlist.Tracks != null && 0 <= playlist.Tracks.Count)
            {
                foreach (var track in playlist.Tracks)
                {
                    args.Tracks.Add(new TrackArg()
                    {
                        Uri = track.Uri
                    });
                }
            }

            var request = JsonRpcFactory.CreateRequest(
                Playlists.MethodSave,
                new
            {
                playlist = args
            }
                );

            var response = await Playlists._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = (response.Result == null)
                ? null
                : JObject.FromObject(response.Result).ToObject <Playlist>();

            return(true, result);
        }
Beispiel #22
0
        public async Task <bool> Seek(int timePosition)
        {
            var request = JsonRpcFactory.CreateRequest(Playback.MethodSeek, new ArgsTimePosition()
            {
                TimePosition = timePosition
            });

            var response = await this._query.Exec(request);

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JValue.FromObject(response.Result).ToObject <bool>();

            return(result);
        }
Beispiel #23
0
        public async Task <Dictionary <string, List <Track> > > Lookup(string[] uris)
        {
            var request = JsonRpcFactory.CreateRequest(Library.MethodLookup, new ArgsUris()
            {
                Uris = uris
            });

            var response = await this._query.Exec(request);

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JObject.FromObject(response.Result).ToObject <Dictionary <string, List <Track> > >();

            return(result);
        }
Beispiel #24
0
        public async Task <List <Ref> > Browse(string uri)
        {
            var request = JsonRpcFactory.CreateRequest(Library.MethodBrowse, new ArgsUri()
            {
                Uri = uri
            });

            var response = await this._query.Exec(request);

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JArray.FromObject(response.Result).ToObject <List <Ref> >();

            return(result);
        }
Beispiel #25
0
        /// <summary>
        /// Get the number of tracks in the history.
        /// </summary>
        /// <returns></returns>
        public static async Task <(bool Succeeded, int Result)> GetLength()
        {
            var request = JsonRpcFactory.CreateRequest(History.MethodGetLength);

            var response = await History._query.Exec(request);

            if (response.Error != null)
            {
                return(false, -1);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JValue.FromObject(response.Result).ToObject <int>();

            return(true, result);
        }
Beispiel #26
0
        /// <summary>
        /// Get the track history.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// The timestamps are milliseconds since epoch.
        /// </remarks>
        public static async Task <(bool Succeeded, Dictionary <long, Ref> Result)> GetHistory()
        {
            var request = JsonRpcFactory.CreateRequest(History.MethodGetHistory);

            var response = await History._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var array  = JArray.FromObject(response.Result);
            var result = new Dictionary <long, Ref>();

            foreach (var child in array.Children())
            {
                if (child.Type != JTokenType.Array)
                {
                    continue;
                }

                long key   = -1;
                Ref  value = null;

                foreach (var elem in child.Children())
                {
                    if (elem.Type == JTokenType.Integer)
                    {
                        key = elem.Value <long>();
                    }
                    if (elem.Type == JTokenType.Object)
                    {
                        value = elem.ToObject <Ref>();
                    }
                }

                if (key != -1 && value != null)
                {
                    result.Add(key, value);
                }
            }

            return(true, result);
        }
Beispiel #27
0
        /// <summary>
        /// Get single mode.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// true : Playback is stopped after current song, unless in repeat mode.
        /// false: Playback continues after current song.
        /// </remarks>
        public static async Task <(bool Succeeded, bool Result)> GetSingle()
        {
            var request = JsonRpcFactory.CreateRequest(Tracklist.MethodGetSingle);

            var response = await Tracklist._query.Exec(request);

            if (response.Error != null)
            {
                return(false, false);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JValue.FromObject(response.Result).ToObject <bool>();

            return(true, result);
        }
Beispiel #28
0
        /// <summary>
        /// Get The playback state.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// After the Play, Pause, Stop and Resume methods,
        /// need to wait a bit for the state to change.
        /// </remarks>
        public static async Task <(bool Succeeded, PlaybackState Result)> GetState()
        {
            var request = JsonRpcFactory.CreateRequest(Playback.MethodGetState);

            var response = await Playback._query.Exec(request);

            if (response.Error != null)
            {
                return(false, PlaybackState.Stopped);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JValue.FromObject(response.Result).ToObject <PlaybackState>();

            return(true, result);
        }
Beispiel #29
0
        /// <summary>
        /// Get version of the Mopidy core API
        /// </summary>
        /// <returns></returns>
        public static async Task <(bool Succeeded, string Result)> GetVersion()
        {
            var request = JsonRpcFactory.CreateRequest(Core.MethodGetVersion);

            var response = await Core._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JValue.FromObject(response.Result).ToObject <string>();

            return(true, result);
        }
Beispiel #30
0
        /// <summary>
        /// Get the list of URI schemes that support playlists.
        /// </summary>
        /// <returns></returns>
        public static async Task <(bool Succeeded, string[] Result)> GetUriSchemes()
        {
            var request = JsonRpcFactory.CreateRequest(Playlists.MethodGetUriSchemes);

            var response = await Playlists._query.Exec(request);

            if (response.Error != null)
            {
                return(false, null);
            }

            // 戻り値の型は、[ JObject | JArray | JValue | null ] のどれか。
            // 型が違うとパースエラーになる。
            var result = JArray.FromObject(response.Result).ToObject <string[]>();

            return(true, result);
        }