コード例 #1
0
        // Schedule Recordings
        /// <summary>
        /// Schedule a recording - this examines the request and populates Service ID, etc.
        /// The MCDATA.Schedule... method should never be called directly outside this method
        /// </summary>
        public static RecordingResult ScheduleRecording(RecordingRequest rr)
        {
            // Populate defaults, e.g. quality, if not set
            PopulateDefaultsIfUnset(ref rr);

            RecordingResult failedResult = new RecordingResult();

            failedResult.Completed = false;

            if (rr.RequestType != RecordingRequestType.Manual)  // manual recordings already have a service ID specified
            {
                if (rr.TVProgrammeID < 1)
                {
                    failedResult.ErrorMessage = "No TV Programme ID was specified.";
                    return(failedResult);
                }

                // Populate the Service ID if not already populated
                TVProgramme tvp = mcData.GetTVProgramme(rr.TVProgrammeID.ToString());
                if (tvp == null)
                {
                    failedResult.ErrorMessage = "No TV Programme with the specified ID could be found.";
                    return(failedResult);
                }

                rr.ServiceID = long.Parse(tvp.ServiceID);  // could fail
            }

            // Get the channel ID from the service ID
            TVService tvs = TVServiceWithIDOrNull(rr.ServiceID.ToString());

            if (tvs == null)
            {
                failedResult.ErrorMessage = "No TV Channel with the retrieved ID could be found.";
                return(failedResult);
            }
            rr.MCChannelID = tvs.MCChannelID;


            // ************** SCHEDULE THE RECORDING ************************
            RPRequest       generatedRequest;
            RecordingResult earlyRecResult;

            if (!mcData.ScheduleRecording(rr, out generatedRequest, out earlyRecResult))
            {
                // Failed already - return the early result
                return(earlyRecResult);
            }


            RecordingResult recResult = mcData.DetermineRecordingResultForRequest(generatedRequest);

            // Success?
            if (recResult.Success)
            {
                // Wait a moment so Scheduler can catch up and associate our request with our recordings...
                System.Threading.Thread.Sleep(600);

                // Now refresh and get the generated recordings...
                EPGManager.ReloadAllRecordings();

                try
                {
                    RPRequest req = recResult.GeneratedRecordingsBlob.RPRequests[0];

                    // Add recordings
                    recResult.GeneratedRecordingsBlob.RPRecordings = req.Recordings();

                    // Add programs linked to these recordings
                    foreach (RPRecording rec in recResult.GeneratedRecordingsBlob.RPRecordings)
                    {
                        TVProgramme tvp = rec.TVProgramme();
                        if (tvp != null)
                        {
                            recResult.GeneratedRecordingsBlob.TVProgrammes.Add(tvp);
                        }
                    }
                }
                catch (Exception ex) {
                    Functions.WriteLineToLogFile("ScheduleRecording(): Error retrieving recordings:");
                    Functions.WriteExceptionToLogFile(ex);
                    recResult.Success      = false;
                    recResult.ErrorMessage = "Exception occured while retrieving recordings - the recording may have been scheduled.";
                }
            }

            return(recResult);
        }
コード例 #2
0
        // Refresh
        public static bool UpdateTVChannels()
        {
            bool debug = ((Settings.Default.DebugChannels) & (Settings.Default.DebugAdvanced));

            Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels() Running:");

            // If we don't have any existing channels at all then get some
            if ((AllTVChannels == null) || (AllTVChannels.Count < 1))
            {
                Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): No existing TV Channels, populating from cache first...");
                if (!PopulateTVChannels(false))
                {
                    return(false);
                }

                Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): Populated from cache: there are " + AllTVChannels.Count.ToString() + " channels.");
                if (AllTVChannels.Count < 1)
                {
                    return(false);
                }
            }

            Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): Backing up " + AllTVChannels.Count.ToString() + " channels.");
            Dictionary <string, TVService> OldTVChannelsKeyedByChannelNumberString = new Dictionary <string, TVService>();

            foreach (TVService tvs in AllTVChannels.Values)
            {
                TVService copiedOldService = tvs.DeepCopy();

                // Skip duplicate keys otherwise you spend 4 hours on a Sunday trying to remotely debug a native code crash
                if (OldTVChannelsKeyedByChannelNumberString.ContainsKey(copiedOldService.ChannelNumberString()))
                {
                    Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels() Skipping service with duplicate channel num string (" + copiedOldService.ChannelNumberString() + ") Callsign is " + copiedOldService.Callsign);
                }
                else
                {
                    Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels() Storing " + copiedOldService.ChannelNumberString() + " : " + copiedOldService.Callsign);
                    OldTVChannelsKeyedByChannelNumberString.Add(copiedOldService.ChannelNumberString(), copiedOldService);
                }
            }

            // Re-populate AllTVChannels from MediaCenter
            Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): Getting newest channels from 7MC...");
            PopulateTVChannels(true);
            Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): Populated from 7MC: there are " + AllTVChannels.Count.ToString() + " channels.");

            // Go through new channels - retrieve isFavourite information and user sort order from old channels
            Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): Merging info from old channels into newer list.");
            List <string> MatchedChannelNumberStrings = new List <string>();

            foreach (TVService newService in AllTVChannels.Values)
            {
                if (OldTVChannelsKeyedByChannelNumberString.ContainsKey(newService.ChannelNumberString()))
                {
                    if (!MatchedChannelNumberStrings.Contains(newService.ChannelNumberString()))
                    {
                        TVService oldService = OldTVChannelsKeyedByChannelNumberString[newService.ChannelNumberString()];

                        // Merge in old user sort and isfavorite information
                        newService.IsFavorite    = oldService.IsFavorite;
                        newService.UserSortOrder = oldService.UserSortOrder;

                        if (newService.MCChannelID != oldService.MCChannelID)
                        {
                            Functions.WriteLineToLogFile("EPG: UpdateTVChannels(): INFORMATION: Service " + newService.Callsign + " changed MC-ID from " + oldService.MCChannelID.ToString() + " to " + newService.MCChannelID.ToString() + " - merging in change.");
                        }
                        if (newService.UniqueId != oldService.UniqueId)
                        {
                            Functions.WriteLineToLogFile("EPG: UpdateTVChannels(): INFORMATION: Service " + newService.Callsign + " changed Unique Service ID from " + oldService.UniqueId + " to " + newService.UniqueId + " - merging in change.");
                        }

                        MatchedChannelNumberStrings.Add(newService.ChannelNumberString());
                    }
                }
                else
                {
                    Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): NEW channel " + newService.Callsign + " was found.  (Chan number " + newService.ChannelNumberString() + ")");
                }
            }

            Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): Merge complete.");

            // Save it
            Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): Saving.");
            SaveChannelsToLocal();

            Functions.WriteLineToLogFileIfSetting(debug, "EPG: UpdateTVChannels(): DONE.");
            return(true);
        }
コード例 #3
0
        public MediaStreamingResult StartStreamer(MediaStreamingRequest request, string HostName, bool dontstart, out bool alreadyexists)
        {
            int newStreamerID = newUniqueID(request, false, dontstart);

            // 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;
                }

                // for liveTV resolve AV sync issue:
                //LiveTVHelpers lth = new LiveTVHelpers();
                //request.CustomParameters.AVSyncDifference = lth.GetMediaSyncDifference(Functions.ToolkitFolder, Functions.StreamBaseFolder, request.InputFile); //for LiveTV
                // Create the streamer
                MediaStreamer mediaStreamer = new MediaStreamer(newStreamerID, request, Functions.ToolkitFolder, Settings.Default.MediaStreamerSecondsToKeepAlive, Settings.Default.DebugAdvancedStreaming);
                mediaStreamer.DebugMessage  += new EventHandler <WasFatAttitude.GenericEventArgs <string> >(mediaStreamer_DebugMessage);
                mediaStreamer.DebugMessage2 += new EventHandler <WasFatAttitude.GenericEventArgs <string> >(mediaStreamer_DebugMessage2);
                mediaStreamer.DebugMessage3 += new EventHandler <WasFatAttitude.GenericEventArgs <string> >(mediaStreamer_DebugMessage3);
                mediaStreamer.DebugMessage4 += new EventHandler <WasFatAttitude.GenericEventArgs <string> >(mediaStreamer_DebugMessage4);

                mediaStreamer.AutoDied += new EventHandler(mediaStreamer_AutoDied);

                MediaStreamingResult result = new MediaStreamingResult();
                try
                {
                    AddNewStreamer(mediaStreamer);
                    Functions.WriteLineToLogFile("MediaStreamer: mediaStreamer object created.");
                    alreadyexists = false;
                    // Try streaming
                    result = mediaStreamer.Configure();  // this does actually begin transcoding
                }
                catch (Exception e)
                {
                    //apparently key already existed
                    alreadyexists = true;
                }


                if (request.NewLiveTV)
                {
                    result.LiveStreamingIndexPath = "/httplivestream/" + newStreamerID.ToString() + "/livetv.m3u8";
                }
                else if (request.UseNewerFFMPEG)
                {
                    result.LiveStreamingIndexPath = "/httplivestream/" + newStreamerID.ToString() + "/index2.m3u8";
                }
                else
                {
                    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);
                alreadyexists = false;
                return(new MediaStreamingResult(MediaStreamingResultCodes.NamedError, e.Message));
            }
        }
コード例 #4
0
 public void CleanUp()
 {
     Functions.WriteLineToLogFile("StreamingManager: Cleaning Up.");
     StopAllStreamers();
 }
コード例 #5
0
 void prober_DebugMessage(object sender, WasFatAttitude.GenericEventArgs <string> e)
 {
     Functions.WriteLineToLogFileIfSetting(Settings.Default.DebugStreaming, e.Value);
 }
コード例 #6
0
        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);
        }