Trakt.tv LiveTV scrobble Development help request. | Page 3

Discussion in 'Plugin Development' started by Alberto83, May 11, 2017.

  1. mm1352000
    • Team MediaPortal

    mm1352000 Development Group

    Joined:
    September 1, 2008
    Messages:
    21,498
    Likes Received:
    4,712
    Ratings:
    +8,175 / 17
    Home Country:
    New Zealand New Zealand
    Okay, well I just repeat the same thing in another way. :)
    The SCR, PTS, DTS and PCR are completely independent of program timing. In a stream provided by TV Server they only give you the time relative to when the person started watching TV with the current tuner. There is no connection to program/"airing" time. Further, there is no guarantee that the TsWriter design won't change in future. In fact, I have changed it in my TVE 3.5 branch so that the time is simply relative to when the person starts watching TV. After that, the time increases continuously regardless of channel and tuner changes.


     
  2. Google AdSense Guest Advertisement



    to hide all adverts.
  3. morpheus_xx
    • Team MediaPortal

    morpheus_xx Lead Dev MP2

    Joined:
    March 24, 2007
    Messages:
    10,852
    Likes Received:
    4,679
    Ratings:
    +6,703 / 11
    Home Country:
    Germany Germany
    Show System Specs
    Ah, this would be the useful information :)

    This is the logic I implemented in my "TimeShiftContext" on client side: it records the "tune in time" and how long the program was running. I just would like a more reliable way, because this implementation expects that the timeshift buffer is infinite, but it is not. So if you watch live TV for hours, you will have obsolete information after tswriter recycles tsbuffer files.
     
  4. Owlsroost
    • Team MediaPortal

    Owlsroost Development Group

    Joined:
    October 28, 2008
    Messages:
    5,500
    Likes Received:
    2,768
    Location:
    Cambridge
    Ratings:
    +4,050 / 1
    Home Country:
    United Kingdom United Kingdom
    Show System Specs
    To add to what mm has said:

    1. All streams (files) that TV Server creates start with all timestamps at zero.
    2. Timeshift streams are part real, part virtual files - the real part (the most recent part) actually exists as files, the virtual part is the older stream data that is no longer available. The timestamps are relative to the start of the virtual file i.e. to zero, and TsReader restricts the seek range to the the 'real' part only (the duration measuring code in TsReader and StreamingServer keeps both a 'real' duration and a 'real+virtual' duration).

    So the only thing TsReader knows is a position (timestamp) in the stream relative to the start of the stream, and the stream duration i.e. end timestamp - start timestamp. It has no concept of real time or date for the stream.
     
  5. Owlsroost
    • Team MediaPortal

    Owlsroost Development Group

    Joined:
    October 28, 2008
    Messages:
    5,500
    Likes Received:
    2,768
    Location:
    Cambridge
    Ratings:
    +4,050 / 1
    Home Country:
    United Kingdom United Kingdom
    Show System Specs
    In terms of timestamps (ignoring the MPEG timestamp rollover), the timeshift stream is infinite - it's only the available data that is finite.

    TsReader knows where it is in the stream, so it could provide a 'current timestamp relative to start of timeshift' value to the player.
     
    • Like Like x 1
  6. Alberto83
    • Team MediaPortal

    Alberto83 Test Group

    Joined:
    August 7, 2012
    Messages:
    336
    Likes Received:
    80
    Gender:
    Male
    Ratings:
    +119 / 1
    Home Country:
    Italy Italy
    I haven't the code here but i'll post the relevant part when i come back home.

    It basically consists in setting a thread.timer to fire up every "tvhandler.nextprogram.starttime" and then resets it with the "tvhandler.nextprogram.starttime" again if the callback function is fired (and the previous tvhandler.nextprogram becomes the tvhandler.currentprogram) or when there's a new tuning event (and thus a new nexprogram on a new channel).
    The callback function of the timer just creates a tscontext with the new program and adds it to the timeshiftmediaitem.TimeshiftContexes manually, without removing the old one (since we're in the same channel). I basically never remove tscontexts but keep adding them and that's why the recycler is needed to remove old entries somehow (or tombestone them). The tscontext.tuneintime is set to datetime.now every time i have to create a new tscontext (so every time a new channel is tuned, or the callback function runs). This way i have a timeshift context is effectively a timeline of the timeshift.

    It's perfectly safe since if, for a moment, we forget that the TS file is "circular", everything before "NOW" in the timeline cannot be changed. It's there and there stays for the whole lifetime of the stream. When the stream is over, we don't need it anymore.
    Also the timer for the next program is safe, because the only thing that could alter that timer is a new tuning event on that stream where we need to reset the timer with a different nextprogram.starttime. Zapping isn't a big deal, we're not tuning while zapping.
    Since i'm using the tvhandler.currentprogram and tvhandler.nexprogram this isn't affected by pausing the tsreader.
    I don't know if i explained that well, i'll post the code.

    When i thought of doing it "server side" i was thinking more of creating the entire TSContext logic on the server (per stream, like now on my solution) and return the relevant portion to the client every time we use the timeshift feature. Since the server, and only the server, can write the stream, it seemed logical to me that it should be the only one that should create and handle this sort of "timeline" and recycle old programs.
    Moreover, this would open up to sharing streams (and it's timeline) to all clients that connect to that stream. (EDIT: i'm more thinking about placeshifting than really sharing the stream)
    Instead of embed those properties in the TS file which seems too complex, what about storing the whole timeline data on the server memory and ask for it from the client based on the tsreader position? This would make them indipendent from the tswriter, right?
     
    Last edited: May 31, 2017
  7. Alberto83
    • Team MediaPortal

    Alberto83 Test Group

    Joined:
    August 7, 2012
    Messages:
    336
    Likes Received:
    80
    Gender:
    Male
    Ratings:
    +119 / 1
    Home Country:
    Italy Italy
    These are the changes to the SlimTVHandler.cs
    Code (C#):
    1.        
    2. /*snip*/
    3. private struct TVSlotContext
    4.         {
    5.             public bool IsPiP;
    6.             public bool CardChanging;
    7.             public string AccessorPath;
    8.             public IChannel Channel;
    9.             //one timer for each slot.
    10.             //@ASK!!! What about doing this server side? one timeline for each stream? Would definitely solve placeshifting issues.
    11.             public Timer nextProgramWatcher;
    12.         }
    13. /*SNIP*/
    14. private bool AddOrUpdateTimeshiftContext(LiveTvMediaItem timeshiftMediaItem, IChannel channel)
    15.         {
    16.             //Do this ASAP so the timer is as close as possible to the real program time change.
    17.             System.DateTime currentTime = System.DateTime.Now;
    18.             //Need to check if a timer is already set before dispose it
    19.             if (_slotContexes[(int)timeshiftMediaItem.AdditionalProperties[LiveTvMediaItem.SLOT_INDEX]].nextProgramWatcher!=null)
    20.                 _slotContexes[(int)timeshiftMediaItem.AdditionalProperties[LiveTvMediaItem.SLOT_INDEX]].nextProgramWatcher.Dispose();
    21.             if (timeshiftMediaItem.TimeshiftContexes.LastOrDefault() != null)
    22.             {
    23.                 //this is not the first context, so so get the one before and set its duration.
    24.                 timeshiftMediaItem.TimeshiftContexes.Last().TimeshiftDuration = currentTime.Subtract(timeshiftMediaItem.TimeshiftContexes.Last().TuneInTime);
    25.             }
    26.             TimeshiftContext tsContext;
    27.             if (CurrentProgram== null) // there's no program information, just go as normal, and don't set a timer to update.
    28.             {
    29.                 tsContext = new TimeshiftContext
    30.                 {
    31.                     Channel = channel,
    32.                     TuneInTime = currentTime,
    33.                 };
    34.             }
    35.             else //populate tscontext with program info and set the timer
    36.             {
    37.                  tsContext = new TimeshiftContext
    38.                 {
    39.                     Channel = channel,
    40.                     TuneInTime = currentTime,
    41.                     Program = CurrentProgram
    42.                 };
    43.                 //Add a timer to trigger an update when next program begins.
    44.                 //Start a new timer to call GetNewProgram when the program is due, plus 15 seconds.
    45.                 _slotContexes[(int)timeshiftMediaItem.AdditionalProperties[LiveTvMediaItem.SLOT_INDEX]].nextProgramWatcher = new Timer(GetNewProgram, timeshiftMediaItem,
    46.                     (tsContext.Program.EndTime - currentTime + System.TimeSpan.FromSeconds(NEXT_PROGRAM_WATCHER_DELAY)), Timeout.InfiniteTimeSpan);
    47.             }
    48.             timeshiftMediaItem.TimeshiftContexes.Add(tsContext);
    49.             timeshiftMediaItem.AdditionalProperties[LiveTvMediaItem.CHANNEL] = channel;
    50.             return true;
    51.         }
    52.         private void GetNewProgram(object o)
    53.         {
    54.             //This will only get called when the current channel does not change.          
    55.             System.DateTime currentTime = (System.DateTime.Now - System.TimeSpan.FromSeconds(NEXT_PROGRAM_WATCHER_DELAY));  //remember the NEXT_PROGRAM_WATCHER_DELAY
    56.             LiveTvMediaItem mi = (LiveTvMediaItem)o;
    57.             //Set offset for the last tscontext
    58.             mi.TimeshiftContexes.LastOrDefault().TimeshiftDuration = (currentTime - mi.TimeshiftContexes.LastOrDefault().TuneInTime);
    59.             //Create the new TSContext
    60.             //first check if the program is null
    61.             if (CurrentProgram == null) //since this function should only triggers when the program change in the current stream, we probably already have epg set, but nobody knows. Bad EPG data?
    62.             {
    63.                 TimeshiftContext tsContext = new TimeshiftContext
    64.                 {
    65.                     Channel = (IChannel)mi.AdditionalProperties[LiveTvMediaItem.CHANNEL],
    66.                     TuneInTime = currentTime,
    67.                 };
    68.             }
    69.             else
    70.             {
    71.                 TimeshiftContext tsContext = new TimeshiftContext
    72.                 {
    73.                     Channel = (IChannel)mi.AdditionalProperties[LiveTvMediaItem.CHANNEL],
    74.                     TuneInTime = currentTime,
    75.                     Program = CurrentProgram  //@NOTE!!!! ok, what if the user changes channel just "a line before??"
    76.                 };
    77.                 //Add the new program to contexes
    78.                 mi.TimeshiftContexes.Add(tsContext);
    79.                 //This is safe
    80.                 mi.AdditionalProperties[LiveTvMediaItem.CURRENT_PROGRAM] = CurrentProgram;
    81.                 mi.AdditionalProperties[LiveTvMediaItem.NEXT_PROGRAM] = (NextProgram != null) ? NextProgram : null;
    82.                 //update timer to the next program change.
    83.                 _slotContexes[(int)mi.AdditionalProperties[LiveTvMediaItem.SLOT_INDEX]].nextProgramWatcher.Change(
    84.                     (tsContext.Program.EndTime - currentTime + System.TimeSpan.FromSeconds(NEXT_PROGRAM_WATCHER_DELAY)), Timeout.InfiniteTimeSpan);
    85.             }
    86.         }
    87. /*snip*/
    88.  
    I could optimize the code by calling again AddOrUpdateTimeshiftContext in the callback function but i wanted to keep it separate for easier debugging (not a pro coder, you can tell from my comments to always know what and why i did something. Need more practice, sorry ) my own code.
    With this changes i could get a timeline with just a few milliseconds delay from the real epg data.
     
  8. ge2301
    • Team MediaPortal

    ge2301 MP2 Design

    Joined:
    January 11, 2014
    Messages:
    5,978
    Likes Received:
    1,469
    Gender:
    Male
    Occupation:
    Automotive Industry
    Location:
    Stuttgart (But living abroad)
    Ratings:
    +2,231 / 2
    Home Country:
    Germany Germany
    @Alberto83 Are you still working on this feature? :)
     
  9. Alberto83
    • Team MediaPortal

    Alberto83 Test Group

    Joined:
    August 7, 2012
    Messages:
    336
    Likes Received:
    80
    Gender:
    Male
    Ratings:
    +119 / 1
    Home Country:
    Italy Italy
    Hello, definitely I am, it's a strong requirement for trakt tv to work for live TV.
    I had a tough week at work but I'm still here.

    I'm trying to find a solution to implement the timeline feature on the slimtvservice instead on the slimtvhandler class. This should be enough to keep it independent from the tswriter but still server handled. While the current "implementation" actually works, it's clumsy because handling any streams information on the client side is logically wrong since the client only reads the stream.
    The main problem other than retrieving and building a timeline for any stream will be to notify then the client of any change on the portion of the program currently playing in the timeline. I'm a newbie coder so everything requires more time for me :)
     
    • Like Like x 2
Loading...

Users Viewing Thread (Users: 0, Guests: 0)

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice
  • About The Project

    The vision of the MediaPortal project is to create a free open source media centre application, which supports all advanced media centre functions, and is accessible to all Windows users.

    In reaching this goal we are working every day to make sure our software is one of the best.

             

  • Support MediaPortal!

    The team works very hard to make sure the community is running the best HTPC-software. We give away MediaPortal for free but hosting and software is not for us.

    Care to support our work with a few bucks? We'd really appreciate it!