// Constructor internal SegmentStoreBroker(string ID, MediaStreamingRequest _request, string pathToTools) { Request = _request; store = new SegmentStore(ID); PathToTools = pathToTools; string rpPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "RemotePotato"); WorkingDirectory = Path.Combine(rpPath, "static\\mediastreams\\" + ID.ToString()); if (!Directory.Exists(WorkingDirectory)) Directory.CreateDirectory(WorkingDirectory); // Probe / Map Audio streams: if (Request.UseAudioStreamIndex >= 0) { SendDebugMessage("MediaStreamer: Mapping streams using requested audio stream " + Request.UseAudioStreamIndex.ToString()); // We still have to probe again to discover the index of the video stream, as both A and V MUST be mapped, can't just map one MapArguments = GetProbeMapArguments(Request.UseAudioStreamIndex); if (string.IsNullOrEmpty(MapArguments)) // May take a small while throw new Exception("Probing failed"); } /* QUICKSTART CODE // So far, so good. If the required segment is available then don't bother starting transcoding; it could already be cached to disk. // Otherwise, let's start transcoding, as the client is likely to request the segment soon. double dStartingSegment = Math.Floor(Convert.ToDouble(Request.StartAt) / Convert.ToDouble(Runner.EncodingParameters.SegmentDuration)); int iStartingSegment = Convert.ToInt32(dStartingSegment); if (! CanGetSegment(iStartingSegment)) // cant get segment { string txtResult = ""; if (!Runner.Start(iStartingSegment, ref txtResult)) throw new Exception("The FFRunner failed to start : " + txtResult); }*/ }
void AddNewStreamer(MediaStreamer newStreamer) { mediaStreamers.Add(newStreamer.ID, newStreamer); if (newStreamer.Request.OnlyTranscodeOnServer) { List <MediaStreamingRequest> msrlist = MediaStreamer.DeserializeTranscodedMSRFromXML(); List <MediaStreamingRequest> msrlist2 = new List <MediaStreamingRequest>(); for (int i = 0; i < msrlist.Count; i++) { MediaStreamingRequest msr = msrlist[i]; if (msr.InputFile.Equals(newStreamer.Request.InputFile) && msr.UniekClientID.Equals(newStreamer.Request.UniekClientID)) { } else { msrlist2.Add(msr); } } msrlist2.Add(newStreamer.Request); MediaStreamer.SerializeTranscodedMSRToXML(msrlist2); } // Power options SetPowerOptions(); }
public SegmentStore(string ID, MediaStreamingRequest request) { this.ID = ID; this.newffmpeg = (request.UseNewerFFMPEG && !request.LiveTV); NewLiveTV = request.NewLiveTV; workingFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "RemotePotato"); workingFolderPath = Path.Combine(workingFolderPath + "\\static\\mediastreams\\", ID); if (!Directory.Exists(workingFolderPath)) Directory.CreateDirectory(workingFolderPath); }
public int newUniqueID(MediaStreamingRequest request, bool getIDOnly, bool dontstart) { if (dontstart) { return(IdsAndInputFilesContains(request.InputFile + request.UniekClientID));//it must exist because this function only gets called when exist in deserialized MediaSteramRequest } else { return(newUniqueID(request, getIDOnly)); } }
public SegmentStore(string ID, MediaStreamingRequest request) { this.ID = ID; this.newffmpeg = (request.UseNewerFFMPEG && !request.LiveTV); NewLiveTV = request.NewLiveTV; workingFolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "RemotePotato"); workingFolderPath = Path.Combine(workingFolderPath + "\\static\\mediastreams\\", ID); if (!Directory.Exists(workingFolderPath)) { Directory.CreateDirectory(workingFolderPath); } }
// Constructor internal SegmentStoreBroker(string ID, MediaStreamingRequest _request, string pathToTools) { Request = _request; store = new SegmentStore(ID, Request); PathToTools = pathToTools; string rpPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "RemotePotato"); WorkingDirectory = Path.Combine(rpPath, "static\\mediastreams\\" + ID.ToString()); if (!Directory.Exists(WorkingDirectory)) { Directory.CreateDirectory(WorkingDirectory); } if (Request.NewLiveTV) { //done in shelCmdRunner return; } // Probe / Map Audio streams: if (Request.NewLiveTV || Request.UseAudioStreamIndex >= 0 || Request.UseSubtitleStreamIndex >= 0 || (Request.UseNewerFFMPEG && !Request.LiveTV)) { SendDebugMessage("MediaStreamer: Mapping streams using requested audio stream " + Request.UseAudioStreamIndex.ToString()); // We still have to probe again to discover the index of the video stream, as both A and V MUST be mapped, can't just map one while (true) { MapArguments = GetProbeMapArguments(Request.UseAudioStreamIndex); if (string.IsNullOrEmpty(MapArguments)) // May take a small while { SendDebugMessage("Probing failed, trying again"); } else { SendDebugMessage("Success! Mappings are :" + MapArguments); break; } } } /* QUICKSTART CODE * // So far, so good. If the required segment is available then don't bother starting transcoding; it could already be cached to disk. * // Otherwise, let's start transcoding, as the client is likely to request the segment soon. * double dStartingSegment = Math.Floor(Convert.ToDouble(Request.StartAt) / Convert.ToDouble(Runner.EncodingParameters.SegmentDuration)); * int iStartingSegment = Convert.ToInt32(dStartingSegment); * if (! CanGetSegment(iStartingSegment)) // cant get segment * { * string txtResult = ""; * if (!Runner.Start(iStartingSegment, ref txtResult)) * throw new Exception("The FFRunner failed to start : " + txtResult); * }*/ }
public MediaStreamingResult StartStreamer(MediaStreamingRequest request, string HostName) { int newStreamerID = newUniqueID(); // Universal workaround: can be removed once new iOS app introduced that sets the Client Device to 'iphone3g' // (desirable to remove it since this will also affect silverlive streaming) if (string.IsNullOrEmpty(request.ClientID)) { request.ClientID = "ios"; request.ClientDevice = "iphone3g"; } try { // Legacy clients (e.g. iOS client) don't have any custom parameters - set them now based on 'Quality' if (!request.UseCustomParameters) // if there are no custom parameters { // Create/update video encoding parameters (also transfers Aspect Ratio into child 'encoding parameters' object) MediaStreamingRequest.AddVideoEncodingParametersUsingiOSQuality(ref request); } /* ************************************************************ * // Override any video encoding parameters from server settings ************************************************************ */ // 1. Audio Volume if (Settings.Default.StreamingVolumePercent != 100) { request.CustomParameters.AudioVolumePercent = Convert.ToInt32(Settings.Default.StreamingVolumePercent); } // 2. Custom FFMPEG template if ((Settings.Default.UseCustomFFMpegTemplate) & (!string.IsNullOrWhiteSpace(Settings.Default.CustomFFMpegTemplate))) { request.CustomParameters.CustomFFMpegTemplate = Settings.Default.CustomFFMpegTemplate.Trim(); } // 3. iPhone 3G requires profile constraints if (request.ClientDevice.ToLowerInvariant() == "iphone3g") { request.CustomParameters.X264Level = 30; request.CustomParameters.X264Profile = "baseline"; } // 4. Deinterlace obvious WMC video if ( (request.InputFile.ToUpper().EndsWith("WTV")) || (request.InputFile.ToUpper().EndsWith("DVR-MS")) ) { request.CustomParameters.DeInterlace = true; } // Create the streamer MediaStreamer mediaStreamer = new MediaStreamer(newStreamerID, request, Functions.ToolkitFolder, Settings.Default.MediaStreamerSecondsToKeepAlive, Settings.Default.DebugAdvancedStreaming); mediaStreamer.DebugMessage += new EventHandler <FatAttitude.GenericEventArgs <string> >(mediaStreamer_DebugMessage); mediaStreamer.AutoDied += new EventHandler(mediaStreamer_AutoDied); AddNewStreamer(mediaStreamer); Functions.WriteLineToLogFile("MediaStreamer: mediaStreamer object created."); // Try streaming MediaStreamingResult result = mediaStreamer.Configure(); // this does actually begin transcoding result.LiveStreamingIndexPath = "/httplivestream/" + newStreamerID.ToString() + "/index.m3u8"; // Add streamer ID to result result.StreamerID = newStreamerID; // Return return(result); } catch (Exception e) { Functions.WriteLineToLogFile("Exception setting up mediaStreaming object:"); Functions.WriteExceptionToLogFile(e); return(new MediaStreamingResult(MediaStreamingResultCodes.NamedError, e.Message)); } }
public int newUniqueID(MediaStreamingRequest request, bool getIDOnly) { int newId = IdsAndInputFilesContains(request.InputFile + request.UniekClientID); if (request.KeepSameIDForSameInputFile && newId != 0) // != 0 means found as existing id that can be resumed { var ms = GetStreamerByID(newId); if (ms != null && !getIDOnly) { //mediaStreamers.Remove(newId); Functions.WriteLineToLogFile("Streamer newId=" + newId + " about to stop (in background), mediaStreamers.ContainsKey(newId) : " + mediaStreamers.ContainsKey(newId)); StopStreamer(newId, 2); Functions.WriteLineToLogFile("Streamer newId=" + newId + " stopped (in background), mediaStreamers.ContainsKey(newId) : " + mediaStreamers.ContainsKey(newId)); } if (!getIDOnly) { DeleteStreamingFiles(newId); //begin anew, s.t. if new quality, this will be used. } //bump up the id in the database db.Delete("IDANDINPUTFILE", String.Format("STREAMID = {0}", "" + newId)); var item = new Dictionary <string, string>(); item.Add("STREAMID", "" + newId); string i = request.InputFile.Replace("'", "''"); string u = request.UniekClientID.Replace("'", "''"); item.Add("INPUTFILE", i + u); db.Insert("IDANDINPUTFILE", item); return(newId); } //clean up if database is large const int maxFileToRememberResume = 1000; int count = 0; Int32.TryParse(db.ExecuteScalar("select COUNT(*) from IDANDINPUTFILE where STREAMID IS NOT NULL;"), out count); if (count > maxFileToRememberResume) { try { DataTable tabel; String query = "select STREAMID, INPUTFILE from IDANDINPUTFILE;"; tabel = db.GetDataTable(query); // The results can be directly applied to a DataGridView control // recipeDataGrid.DataSource = tabel; // Or looped through for some other reason var i = 0; foreach (DataRow r in tabel.Rows) { if (i < count / 2) { db.ExecuteNonQuery("delete from IDANDINPUTFILE where STREAMID=" + r["STREAMID"] + ";"); } else { } i++; } } catch (Exception fail) { String error = "The following error has occurred in cleaning up database : " + db.ToString() + "\n"; error += fail.Message; if (Settings.Default.DebugStreaming) { Functions.WriteLineToLogFile("StreamingManager: " + error); } } } do { var r = new Random(); //newId = (getIDOnly ? r.Next(100000, 999999) : r.Next(10000, 99999)); newId = r.Next(10000, 99999); } while (mediaStreamers.ContainsKey(newId) || !IdsAndInputFilesContains(newId).Equals("")); if (IdsAndInputFilesContains(request.InputFile + request.UniekClientID) == 0 && !request.InputFile.Contains("RMCLiveTV")) //live tv gets a new iD all the time anyway, due to randowm nr in inputfile string { var item = new Dictionary <string, string>(); item.Add("STREAMID", "" + newId); string i = request.InputFile.Replace("'", "''"); string u = request.UniekClientID.Replace("'", "''"); item.Add("INPUTFILE", i + u); db.Insert("IDANDINPUTFILE", item); // db.CommitTransaction(); } return(newId); }