示例#1
0
 public WebStringResult StartStreamWithStreamSelection(string identifier, string profileName, long startPosition, int audioId, int subtitleId)
 {
     StreamLog.Debug(identifier, "Called StartStreamWithStreamSelection with profile={0}; start={1}; audioId={2}; subtitleId={3}",
                     profileName, startPosition, audioId, subtitleId);
     _stream.EndStream(identifier); // first end previous stream, if any available
     return(_stream.StartStream(identifier, Configuration.StreamingProfiles.GetTranscoderProfileByName(profileName), startPosition * 1000, audioId, subtitleId));
 }
示例#2
0
        public WebBoolResult InitStream(WebMediaType type, int?provider, string itemId, int?offset, string clientDescription, string identifier, int?idleTimeout)
        {
            AuthorizeStreaming();
            if (type == WebMediaType.TV)
            {
                int channelId = Int32.Parse(itemId);
                lock (_timeshiftings)
                {
                    StreamLog.Info(identifier, "Starting timeshifting on channel {0} for client {1}", channelId, clientDescription);
                    var card = Connections.TAS.SwitchTVServerToChannelAndGetVirtualCard("mpextended-" + identifier, channelId);
                    if (card == null)
                    {
                        StreamLog.Error(identifier, "Failed to start timeshifting for stream");
                        return(false);
                    }
                    else
                    {
                        StreamLog.Debug(identifier, "Timeshifting started!");
                        _timeshiftings[identifier] = card;
                        itemId = card.TimeShiftFileName;
                    }
                }
            }

            StreamLog.Info(identifier, "Called InitStream with type={0}; provider={1}; itemId={2}; offset={3}; clientDescription={4}; idleTimeout={5}",
                           type, provider, itemId, offset, clientDescription, idleTimeout);
            return(_stream.InitStream(identifier, clientDescription, new MediaSource(type, provider, itemId, offset), idleTimeout.HasValue ? idleTimeout.Value : 5 * 60));
        }
示例#3
0
        public Stream DoStream(WebMediaType type, int?provider, string itemId, string clientDescription, string profileName, long startPosition, int?idleTimeout)
        {
            if (!IsClientAuthorized())
            {
                Log.Warn("Host {0} isn't authorized to call DoStream", WCFUtil.GetClientIPAddress());
                WCFUtil.SetResponseCode(HttpStatusCode.Unauthorized);
                return(Stream.Null);
            }

            // calculate timeout, which is by default 5 minutes for direct streaming and 5 seconds for transcoded streams
            var profile = Configuration.StreamingProfiles.Transcoders.FirstOrDefault(x => x.Name == profileName);

            if (profile == null)
            {
                Log.Warn("Called DoStream with non-existing profile {0}", profileName);
                return(Stream.Null);
            }
            int timeout = profile.Transcoder == typeof(Transcoders.Direct).FullName ? 5 * 60 : 5;

            if (idleTimeout.HasValue)
            {
                timeout = idleTimeout.Value;
            }

            // This only works with profiles that actually return something in the RetrieveStream method (i.e. no RTSP or CustomTranscoderData)
            string identifier = String.Format("dostream-{0}", new Random().Next(10000, 99999));

            StreamLog.Debug(identifier, "DoStream: using timeout={0}", timeout);

            if (!InitStream(type, provider, itemId, null, clientDescription, identifier, timeout))
            {
                StreamLog.Info(identifier, "DoStream: InitStream() failed");
                FinishStream(identifier);
                return(Stream.Null);
            }

            if (String.IsNullOrEmpty(StartStream(identifier, profileName, startPosition)))
            {
                StreamLog.Info(identifier, "DoStream: StartStream failed");
                FinishStream(identifier);
                return(Stream.Null);
            }

            StreamLog.Info(identifier, "DoStream: succeeded, returning stream");
            return(RetrieveStream(identifier));
        }
示例#4
0
        public WebBoolResult FinishStream(string identifier)
        {
            StreamLog.Debug(identifier, "Called FinishStream");
            _stream.KillStream(identifier);

            lock (_timeshiftings)
            {
                if (_timeshiftings.ContainsKey(identifier) && _timeshiftings[identifier] != null)
                {
                    StreamLog.Info(identifier, "Cancelling timeshifting");
                    Connections.TAS.CancelCurrentTimeShifting("mpextended-" + identifier);
                    _timeshiftings.Remove(identifier);
                }
            }

            return(true);
        }
示例#5
0
        public bool Stop()
        {
            StreamLog.Debug(context.Identifier, "VLCManagedEncoder: Stopping transcoding");
            try
            {
                DataOutputStream.Close();
            }
            catch (Exception e)
            {
                StreamLog.Info(context.Identifier, "VLCManagedEncoder: Failed to close data output stream", e);
            }

            inputTimer.Enabled = false;
            StreamLog.Trace(context.Identifier, "VLCManagedEncoder: Trying to stop vlc");
            transcoder.StopTranscoding();
            transcoder = null;
            StreamLog.Debug(context.Identifier, "VLCManagedEncoder: Stopped transcoding");

            return(true);
        }
示例#6
0
        public bool Setup()
        {
            // setup output named pipe
            DataOutputStream = new NamedPipe();
            string output = ((NamedPipe)DataOutputStream).Url;

            StreamLog.Info(context.Identifier, "VLCManagedEncoder: starting output named pipe {0}", output);
            ((NamedPipe)DataOutputStream).Start(false);

            // prepare sout, needs some trickery for vlc
            string realSout = sout.Replace("#OUT#", @"\" + output);

            // debug
            StreamLog.Debug(context.Identifier, "VLCManagedEncoder: sout {0}", realSout);
            StreamLog.Debug(context.Identifier, "VLCManagedEncoder: arguments {0}", String.Join("|", arguments));

            // start vlc
            transcoder = new VLCTranscoder();
            transcoder.SetArguments(arguments);
            transcoder.SetMediaName(Guid.NewGuid().ToString());
            transcoder.SetSout(realSout);

            // setup input
            if (inputMethod == InputMethod.NamedPipe)
            {
                transcoderInputStream = new NamedPipe();
                StreamLog.Info(context.Identifier, "VLCManagedEncoder: starting input named pipe {0}", transcoderInputStream);
                ((NamedPipe)transcoderInputStream).Start(false);
                inputPath = "stream://" + transcoderInputStream.Url; // use special syntax for VLC to pick up named pipe
            }
            StreamLog.Debug(context.Identifier, "VLCManagedEncoder: input {0}", inputPath);
            transcoder.SetInput(inputPath);

            // start transcoding
            transcoder.StartTranscoding();
            // doesn't work
            //transcoder.Seek(startPos * 1.0 / context.MediaInfo.Duration * 1000);

            context.TranscodingInfo.Supported = true;
            return(true);
        }
示例#7
0
        public bool Stop()
        {
            // close streams
            CloseStream(InputStream, "input");
            CloseStream(transcoderInputStream, "transcoder input");
            CloseStream(DataOutputStream, "transcoder output");

            try
            {
                if (transcoderApplication != null && !transcoderApplication.HasExited)
                {
                    StreamLog.Debug(context.Identifier, "Encoding: Killing transcoder");
                    transcoderApplication.Stop();
                }
            }
            catch (Exception e)
            {
                StreamLog.Error(context.Identifier, "Encoding: Failed to kill transcoder", e);
            }

            return(true);
        }
示例#8
0
 public WebBoolResult StopStream(string identifier)
 {
     StreamLog.Debug(identifier, "Called StopStream");
     _stream.EndStream(identifier);
     return(true);
 }
示例#9
0
 public WebStringResult StartStream(string identifier, string profileName, long startPosition)
 {
     StreamLog.Debug(identifier, "Called StartStream with profile={0}; start={1}", profileName, startPosition);
     _stream.EndStream(identifier); // first end previous stream, if any available
     return(_stream.StartStream(identifier, Configuration.StreamingProfiles.GetTranscoderProfileByName(profileName), startPosition * 1000));
 }