コード例 #1
0
 public static string GetYTVideoId(string url)
 {
     try {
         return(VideoId.TryParse(url)?.Value);
     }
     catch (Exception) {
         return("");
     }
 }
コード例 #2
0
        public void I_can_specify_a_valid_video_url_in_place_of_an_id(string videoUrl, string expectedVideoId)
        {
            // Act
            var result      = new VideoId(videoUrl);
            var maybeResult = VideoId.TryParse(videoUrl);

            // Assert
            result.Value.Should().Be(expectedVideoId);
            maybeResult.Should().Be(result);
        }
コード例 #3
0
        public void I_can_specify_a_valid_video_id(string videoId)
        {
            // Act
            var result      = new VideoId(videoId);
            var maybeResult = VideoId.TryParse(videoId);

            // Assert
            result.Value.Should().Be(videoId);
            maybeResult.Should().Be(result);
        }
コード例 #4
0
 public void I_cannot_specify_an_invalid_video_url_in_place_of_an_id(string videoUrl)
 {
     // Act & assert
     Assert.Throws <ArgumentException>(() => new VideoId(videoUrl));
     VideoId.TryParse(videoUrl).Should().BeNull();
 }
コード例 #5
0
        public async Task PlayAsync(params string[] Args)
        {
            if (Client.State == PlayerState.Paused)
            {
                Client.State = PlayerState.Playing;
                return;
            }
            EmbedBuilder Builder = new EmbedBuilder()
            {
                Color = Client.Color,
                Title = GetEntry("Enqueue")
            };

            if (Args.Length > 0)
            {
                if (Args[0] == "soundcloud" && Args.Length > 1)
                {
                    if (Args[1] == "playlist" && Args.Length > 2)
                    {
                        List <Models.SoundCloud.Playlist> playlists = Client.SearchSoundCloudPlaylist(string.Join(" ", Args.Skip(2)));

                        Models.SoundCloud.Playlist playlist = await Global.MusicHandler.Select(Client, playlists, Context, Language);

                        if (playlist == null)
                        {
                            Builder.Description = GetEntry("SCPlaylistCancelled");
                            await Context.Channel.SendMessageAsync("", embed : Builder.Build());
                        }
                        else
                        {
                            Client.Enqueue(playlist);

                            Builder.Url         = playlist.Url;
                            Builder.Description = GetEntry("SCPlaylistEnqueued");
                            Builder.AddField(GetEntry("TitleTrackCount"), playlist.Title + " | " + playlist.TrackCount);
                            Builder.AddField(GetEntry("PlaylistMadeBy"), playlist.User.Username);
                            Builder.ThumbnailUrl = playlist.ThumbnailUrl;

                            await Context.Channel.SendMessageAsync("", embed : Builder.Build());

                            if (Client.State < PlayerState.Playing)
                            {
                                await Client.PlayAsync(Context);
                            }
                        }
                    }
                    else
                    {
                        List <Models.SoundCloud.Track> tracks = Client.SearchSoundCloudTrack(string.Join(" ", Args.Skip(1)));

                        Models.SoundCloud.Track track = await Global.MusicHandler.Select(Client, tracks, Context, Language);

                        if (track == null)
                        {
                            Builder.Description = GetEntry("SCTrackCancelled");
                            await Context.Channel.SendMessageAsync("", embed : Builder.Build());
                        }
                        else
                        {
                            Client.Enqueue(track);
                            if (Client.State < PlayerState.Playing)
                            {
                                await Client.PlayAsync(Context);
                            }
                            else
                            {
                                Builder.Url         = track.Url;
                                Builder.Description = GetEntry("SCTrackEnqueued");
                                Builder.AddField(GetEntry("TitleUploadedBy"), track.Title + " | " + track.User.Username);
                                Builder.ThumbnailUrl = track.ThumbnailUrl;

                                await Context.Channel.SendMessageAsync("", embed : Builder.Build());
                            }
                        }
                    }
                }
                else if (Args[0].ToLower() == "listen.moe")
                {
                    Client.EnqueueLISTENmoe(Args.Length > 1 && Args[1].ToLower() == "kpop");
                    Builder.Description = "LISTEN.moe";
                    await Context.Channel.SendMessageAsync("", embed : Builder.Build());

                    if (Client.State < PlayerState.Playing)
                    {
                        await Client.PlayAsync(Context);
                    }
                }
                else
                {
                    string        url    = string.Join(" ", Args);
                    YoutubeClient client = new YoutubeClient();
                    PlaylistId?   id     = PlaylistId.TryParse(url);
                    if (id.HasValue)
                    {
                        List <PlaylistVideo> videos = await client.Playlists.GetVideosAsync(id.Value).ToListAsync();

                        if (videos.Count == 0)
                        {
                            Builder.Description = GetEntry("YTPlaylistEmpty");
                            await Context.Channel.SendMessageAsync("", embed : Builder.Build());
                        }
                        else
                        {
                            YoutubeExplode.Playlists.Playlist playlist = await client.Playlists.GetAsync(id.Value);

                            Client.Enqueue(playlist);

                            if (Client.State < PlayerState.Playing)
                            {
                                await Client.PlayAsync(Context);
                            }
                            else
                            {
                                Builder.Url         = playlist.Url;
                                Builder.Description = GetEntry("YTPlaylistEnqueued");
                                Builder.AddField(GetEntry("TitleUploadedBy"), playlist.Title + " | " + playlist.Author);
                                Builder.ThumbnailUrl = videos[0].Thumbnails.GetMaxResUrl();

                                await Context.Channel.SendMessageAsync("", embed : Builder.Build());
                            }
                        }
                    }
                    VideoId?vid = VideoId.TryParse(url);
                    if (vid.HasValue)
                    {
                        Video video = await client.Videos.GetAsync(vid.Value);
                        await EnqueueVideo(video, Builder);
                    }
                    else
                    {
                        List <VideoSearchResult> videos = await Client.SearchYouTubeVideoAsync(url);

                        VideoSearchResult video = await Global.MusicHandler.Select(Client, videos, Context, Language);

                        if (video == null)
                        {
                            Builder.Description = GetEntry("YTVideoCancelled");
                            await Context.Channel.SendMessageAsync("", embed : Builder.Build());
                        }
                        else
                        {
                            await EnqueueVideo(video, Builder);
                        }
                    }
                }
            }
            else
            {
                if (Client.Queue.Count != 0 && Client.State < PlayerState.Playing)
                {
                    await Client.PlayAsync(Context);
                }
                else
                {
                    await Context.Channel.SendMessageAsync(GetEntry("Empty"));
                }
            }
        }
コード例 #6
0
ファイル: Music.cs プロジェクト: ExModify/Chino-chan
        public async Task PlayAsync(ICommandContext Context, ITextChannel Channel = null, bool KeepCurrent = false, TimeSpan?SeekTo = null, bool AvoidState = false)
        {
            if (Channel == null)
            {
                Channel = Context.Channel as ITextChannel;
            }

            string lId = Channel.GetSettings().Language;

            LanguageEntry Language = Global.Languages.GetLanguage(lId);

            if (!AvoidState)
            {
                if (State == PlayerState.Playing || State == PlayerState.Paused)
                {
                    await Channel.SendMessageAsync(Language.GetEntry("MusicHandler:AlreadyPlaying"));

                    return;
                }
            }
            if (State == PlayerState.Disconnected)
            {
                bool Success = await ConnectAsync(Context);

                if (!Success)
                {
                    return;
                }
            }
            if (!KeepCurrent || Current == null)
            {
                Current = Queue[QueueIndex];
            }

            string Url = Current.UrlOrId;

            WebSocket ws = null;

            if (Current.IsYouTube)
            {
                YoutubeClient  Client = new YoutubeClient();
                StreamManifest sm     = null;
                try
                {
                    sm = await Client.Videos.Streams.GetManifestAsync(VideoId.TryParse(Current.UrlOrId).Value);
                }
                catch (Exception e)
                {
                    File.WriteAllText("tempexceptionfrommusicplayer.json", JsonConvert.SerializeObject(e, Formatting.Indented));

                    await Global.Client.GetGuild(Global.Settings.DevServer.Id)
                    .GetTextChannel(Global.Settings.DevServer.ErrorReportChannelId).SendFileAsync("tempexceptionfrommusicplayer.json", "");

                    File.Delete("tempexceptionfrommusicplayer.json");
                }
                if (sm != null)
                {
                    IEnumerable <IAudioStreamInfo> streamInfos = sm.GetAudioStreams();

                    if (streamInfos.Count() > 0)
                    {
                        IStreamInfo info = streamInfos.GetWithHighestBitrate();
                        Url = info.Url;
                    }
                }

                if (Url == Current.UrlOrId)
                {
                    Url = null;
                }
            }
            else
            {
                if (Current.IsListenMoe)
                {
                    Url = Current.PublicUrl;
                    ws  = new WebSocket(Current.PublicUrl.Contains("kpop") ? "wss://listen.moe/kpop/gateway_v2" : "wss://listen.moe/gateway_v2");

                    Timer t = new Timer((state) =>
                    {
                        try
                        {
                            ws.Send("{ \"op\": 9 }");
                        }
                        catch
                        {
                            Logger.Log(LogType.WebSocket, ConsoleColor.Red, "Error", "Couldn't send heartbeat to LISTEN.moe!");
                        }
                    }, null, -1, -1);

                    ws.OnOpen += (s, e) =>
                    {
                        ws.Send("{ \"op\": 0, \"d\": { \"auth\": \"\" } }"); // { op: 0, d: { auth: "" } }
                    };
                    ws.OnMessage += (s, e) =>
                    {
                        ListenMoe parsed = JsonConvert.DeserializeObject <ListenMoe>(e.Data);
                        if (parsed.OpCode == 0)
                        {
                            t.Change(0, parsed.Data.HeartBeat);
                        }
                        else if (parsed.OpCode == 1 && parsed.Type == "TRACK_UPDATE")
                        {
                            ListenMoeStartTime = parsed.Data.StartTime;
                            Current.Author     = string.Join(" && ", parsed.Data.Song.Artists.Select(i => i.NameRomaji ?? i.Name));
                            Current.Duration   = TimeSpan.FromSeconds(parsed.Data.Song.Duration);
                            Current.Title      = parsed.Data.Song.Title;
                            Current.Thumbnail  = null;
                            foreach (ListenMoeAlbum album in parsed.Data.Song.Albums)
                            {
                                if (album.Image != null)
                                {
                                    Current.Thumbnail = album.Image;
                                    break;
                                }
                            }
                            if (State > PlayerState.Connected && State != PlayerState.Paused)
                            {
                                SendNowPlayingAsync(Context, Channel).GetAwaiter().GetResult();
                            }
                        }
                    };
                    ws.OnClose += (s, e) =>
                    {
                        t.Change(Timeout.Infinite, Timeout.Infinite);
                        t.Dispose();
                    };

                    ws.Connect();
                }
                else if (Global.SoundCloud == null)
                {
                    if (!IterateIndex(true))
                    {
                        Current = null;
                        await Channel.SendMessageAsync(Language.GetEntry("MusicHandler:SoundCloudNotAvailable"));
                    }
                    else
                    {
                        await Channel.SendMessageAsync(Language.GetEntry("MusicHandler:OnlySoundCloudTracks"));

                        new Task(async() => await PlayAsync(Context, Channel, AvoidState: true));
                    }
                    return;
                }
                else
                {
                    Url += "?client_id=" + Global.SoundCloud.ClientId;
                }
            }

            if (Url == null)
            {
                if (!IterateIndex())
                {
                    Current = null;
                    await Channel.SendMessageAsync(Language.GetEntry("MusicHandler:FinishedPlaying"));

                    State = PlayerState.Connected;
                }
                else
                {
                    new Task(async() => await PlayAsync(Context, Channel, AvoidState: true)).Start();
                    return;
                }
            }

            try
            {
                Reader = new FFmpegReader(Url);

                /*
                 * switch (encoding.Name)
                 * {
                 *  case "webm":
                 *  case "3gpp":
                 *      Stream s = await new HttpClient().GetStreamAsync(Url);
                 *      Reader = new NAudio.Vorbis.VorbisWaveReader(s);
                 *      break;
                 *
                 *  default:
                 *      Reader = new MediaFoundationReader(Url);
                 *      break;
                 * }
                 */
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e);
                await Channel.SendMessageAsync(Language.GetEntry("MusicHandler:SongInaccessible", "SONGNAME", Current.Title));

                if (!IterateIndex(Global.SoundCloud == null))
                {
                    Current = null;
                    await Channel.SendMessageAsync(Language.GetEntry("MusicHandler:FinishedPlaying"));

                    State = PlayerState.Connected;
                }
                else
                {
                    new Task(async() => await PlayAsync(Context, Channel, AvoidState: true)).Start();
                }
                return;
            }

            if (PCMStream == null || !PCMStream.CanWrite)
            {
                PCMStream = Client.CreatePCMStream(AudioApplication.Music, 128 * 1024, 200, 0);
            }

            //WaveFormat OutFormat = new WaveFormat(48000, 16, 2);


            /*
             * MediaFoundationResampler Resampler = new MediaFoundationResampler(Reader, OutFormat)
             * {
             *  ResamplerQuality = 60
             * };
             */

            //if (SeekTo.HasValue && !Current.IsListenMoe) Reader.CurrentTime = SeekTo.Value;
            if (SeekTo.HasValue && SeekTo != TimeSpan.Zero && !Current.IsListenMoe)
            {
                Reader.ReadUntil(SeekTo.Value);
            }
            BackupTime = TimeSpan.Zero;

            //int Size = OutFormat.AverageBytesPerSecond / 50;
            int Size = Reader.BufferSize(1);

            byte[] Buffer = new byte[Size];
            int    Count  = 0;

            State         = PlayerState.Playing;
            TextChannelId = Channel.Id;
            if (!Current.IsListenMoe)
            {
                await SendNowPlayingAsync(Context, Channel);
            }

            /*while (Reader.CanRead && (Count = Resampler.Read(Buffer, 0, Size)) > 0
             *  && Request == PlayerRequest.Idle && State > PlayerState.Connected)*/
            while (Reader.CanRead && (Count = Reader.Read(Buffer, 0, Size)) > 0 &&
                   Request == PlayerRequest.Idle && State > PlayerState.Connected)
            {
                if (State == PlayerState.Paused)
                {
                    await Channel.SendMessageAsync("", embed : new EmbedBuilder()
                    {
                        Title = Language.GetEntry("MusicHandler:Paused"),
                        Color = Color
                    }.Build());


                    while (State == PlayerState.Paused && Request == PlayerRequest.Idle)
                    {
                        Thread.Sleep(100);
                    }

                    string cId = Channel.GetSettings().Language;
                    if (cId != lId)
                    {
                        Language = Global.Languages.GetLanguage(cId);
                    }
                    lId = cId;

                    if (State == PlayerState.Playing)
                    {
                        await Channel.SendMessageAsync("", embed : new EmbedBuilder()
                        {
                            Title = Language.GetEntry("MusicHandler:Resumed"),
                            Color = Color
                        }.Build());

                        if (Current.IsListenMoe)
                        {
                            await SendNowPlayingAsync(Context, Channel);
                        }
                    }
                }
                if (Request > 0)
                {
                    break;
                }

                if (CurrentTime.TotalSeconds % 10 == 0 && BackupTime.TotalSeconds != CurrentTime.TotalSeconds)
                {
                    PropertyChanged?.Invoke();
                    BackupTime = CurrentTime;
                }

                try
                {
                    if (State < PlayerState.Playing)
                    {
                        break;
                    }
                    ChangeVolume(Buffer, Volume / 100f);
                    await PCMStream.WriteAsync(Buffer, 0, Count);
                }
                catch (Exception e)
                {
                    if (State == PlayerState.Disconnected || Client.ConnectionState == ConnectionState.Disconnected || Client.ConnectionState == ConnectionState.Disconnecting)
                    {
                        break;
                    }

                    string cId = Channel.GetSettings().Language;
                    if (cId != lId)
                    {
                        Language = Global.Languages.GetLanguage(cId);
                    }
                    lId = cId;

                    await Channel.SendMessageAsync(Language.GetEntry("MusicHandler:PlaybackErrorOccured"));

                    Request = PlayerRequest.Stop;
                    Logger.Log(LogType.Music, ConsoleColor.Red, "Error", e.ToString());
                    if (Global.Settings.DevServer.ErrorReportChannelId != 0)
                    {
                        ITextChannel Report = Global.Client.GetChannel(Global.Settings.DevServer.ErrorReportChannelId) as ITextChannel;
                        await Report.SendMessageAsync($"An error occured while playing on a server!\n```\n{ e }\n```\n" +
                                                      $"Client:\n { JsonConvert.SerializeObject(this) }");
                    }
                    break;
                }
            }
            if (ws != null && ws.IsAlive)
            {
                ws.Close();
            }

            if (Request == PlayerRequest.Idle && State > PlayerState.Connected)
            {
                Request = PlayerRequest.Next;
            }

            //Resampler.Dispose();
            Reader.Dispose();
            Reader = null;
            //Resampler = null;
            try { await PCMStream.FlushAsync(); } catch { } // It may be disposed

            if (Request == PlayerRequest.Next)
            {
                Request = PlayerRequest.Idle;
                if (!IterateIndex(Global.SoundCloud == null))
                {
                    if (State != PlayerState.Connected && State != PlayerState.Disconnected)
                    {
                        State = PlayerState.Connected;
                    }
                    Current = null;

                    string cId = Channel.GetSettings().Language;
                    if (cId != lId)
                    {
                        Language = Global.Languages.GetLanguage(cId);
                    }
                    lId = cId;

                    await Channel.SendMessageAsync(Language.GetEntry("MusicHandler:FinishedPlaying"));
                }
            }
            else if (Request == PlayerRequest.Stop)
            {
                Request = PlayerRequest.Idle;
                State   = PlayerState.Connected;
                Current = null;
            }

            if (State > PlayerState.Connected)
            {
                new Task(async() => await PlayAsync(Context, Channel, AvoidState: true)).Start();
            }
        }