示例#1
0
        /// <summary>
        /// Start the stream
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task <bool> Start(int id)
        {
            Stream stream;

            // Stream does not exist
            if ((stream = await _streamLogic.For(_user).Get(id)) == null)
            {
                return(false);
            }

            // Stream already started
            if (_state.StreamItems.ContainsKey(id) && _state.StreamItems[id].State == StreamStatusEnum.Started)
            {
                return(false);
            }

            var streamRipperInstance = _streamRipperProxy.Proxy(new Uri(stream.Url));

            streamRipperInstance.SongChangedEventHandlers += async(_, arg) =>
            {
                var songMetaData = arg.SongInfo.SongMetadata;

                var track    = $"{songMetaData.Artist}-{songMetaData.Title}";
                var filename = $"{track}.mp3";

                if (_filterSongLogic.ShouldInclude(arg.SongInfo.Stream, track, stream.Filter, out var duration))
                {
                    var aggregatedSink = await _sinkService.ResolveStreamSink(stream);

                    // Upload the stream
                    await aggregatedSink(arg.SongInfo.Stream.Reset(), filename);

                    var extendedSongMetadata = await _songMetaDataExtract.Populate(ExtendedSongMetadata.Extend(
                                                                                       arg.SongInfo.SongMetadata, x =>
                    {
                        x.Duration = duration;
                    }));

                    // Invoke socket
                    await _hub.Clients.User(_user.Id.ToString()).SendAsync("download",
                                                                           filename,
                                                                           extendedSongMetadata,
                                                                           arg.SongInfo.Stream.Reset().ConvertToBase64(),
                                                                           new { stream.Name, stream.Id }
                                                                           );
                }
                else
                {
                    await _hub.Clients.User(_user.Id.ToString())
                    .SendAsync("log", $"Stream {id} with name {filename} skipped");
                }
            };

            streamRipperInstance.StreamEndedEventHandlers += async(sender, arg) =>
            {
                await _hub.Clients.User(_user.Id.ToString()).SendAsync("log", $"Stream {id} ended");

                _state.StreamItems[id].State = StreamStatusEnum.Stopped;
            };

            streamRipperInstance.StreamFailedHandlers += async(sender, arg) =>
            {
                await _hub.Clients.User(_user.Id.ToString()).SendAsync("log", $"Stream {id} failed", arg.Exception?.Message);

                _state.StreamItems[id].State = StreamStatusEnum.Fail;

                _logger.LogError($"Failed to start {id}", arg.Exception);
            };

            streamRipperInstance.StreamStartedEventHandlers += async(sender, arg) =>
            {
                await _hub.Clients.User(_user.Id.ToString()).SendAsync("log", $"Stream {id} started");
            };

            streamRipperInstance.StreamUpdateEventHandlers += async(sender, arg) =>
            {
                await _hub.Clients.User(_user.Id.ToString()).SendAsync("log",
                                                                       $"Stream {id} updated with {arg.SongRawPartial.Length} bytes");
            };

            // Start the ripper
            streamRipperInstance.Start();

            // Add to the dictionary
            _state.StreamItems[id] = new StreamItem
            {
                User         = _user,
                StreamRipper = streamRipperInstance,
                State        = StreamStatusEnum.Started
            };

            await _configLogic.UpdateGlobalConfig(c => new GlobalConfigViewModel(c)
            {
                StartedStreams = c.StartedStreams.Add(id)
            });

            return(true);
        }