mrworf / plexupdate

Plex Update script to simplify the life of Linux Plex Media Server users.
GNU General Public License v2.0
1.75k stars 145 forks source link

In Use Check #177

Closed arkestlerdev closed 6 years ago

arkestlerdev commented 7 years ago

When the script checks to see if the server is in use, is it aware of DVR recording or DVR Post Processing scripts? I would hate for the update to kill a recording or post processing script.

Thank you.

demonbane commented 7 years ago

plexupdate uses the same API as the "Now Playing" tab in the Plex Web UI. I don't do any DVR stuff so I can't test it myself, but if DVR activity shows up in "Now Playing" it should be fine. If not, we'd need to find a way to check for DVR activity through the API.

arkestlerdev commented 7 years ago

Unfortunately, there is no DVR activity reported in the Now Playing Tab. The only thing I can tell that happens is the status log records an entry like "Recording E10 - Battles Premiere, Part 2" and once complete that the recording has completed.

demonbane commented 7 years ago

@neo-17 I just posted a question on the forums to see if there's any way we can get that status. If there is a way I'll try to get it added since having a recording cut out right in the middle would really suck. :)

demonbane commented 7 years ago

@neo-17 A couple of people responded with possible ways of checking, but I don't have any DVR devices to be able to test this unfortunately. If you could test these and let me know what type of data you get back from each one I can try to add support for it:

https://forums.plex.tv/discussion/comment/1404658#Comment_1404658

If you need any help figuring out how to do the tests just let me know and I'll try to walk you through it.

arkestlerdev commented 7 years ago

I would be glad to help test those out, but I am not sure about how to go about it. If you give me some direction on what to do, I'll be glad to post the resulting data.

mrworf commented 7 years ago

Here's what we need:

First, login to your plex server and get the PlexOnlineToken from "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Preferences.xml" ... It's the field called "PlexOnlineToken"

Next, while you're still logged in, initiate a recording on Plex and then issue the following commands and post the output here (please obscure any token or you can also email me if you prefer)

curl http://localhost:32400/livetv?X-Plex-Token=<insert token here without quotes>
curl http://localhost:32400/livetv/dvrs?X-Plex-Token=<insert token here without quotes>

From the output of the last one, I'm guessing there should be some kind of unique identifier for each DVR you have, go through each one (if more than one) and issue the following command:

curl http://localhost:32400/<dvr id>?X-Plex-Token=<insert token here without quotes>

(if the command fails, you've probably got the wrong id, so make sure to test with all available ids)

Once you've done all this, please stop the recording and redo the same steps again (so we can compare differences).

This should give us a very good starting point and hopefully should be able to implement the DVR detection.

If you want, you can email me and I'll invite you to the slack channel and we can chat directly. But regardless, if you do the above steps, we should be fine πŸ˜„

arkestlerdev commented 7 years ago

Ok, thanks. I will run those tests and post the output. Do you need the output from all the commands or just the last one?

On Mar 29, 2017, at 12:31 PM, Henric Andersson notifications@github.com wrote:

Here's what we need:

First, login to your plex server and get the PlexOnlineToken from "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Preferences.xml" ... It's the field called "PlexOnlineToken"

Next, while you're still logged in, initiate a recording on Plex and then issue the following commands and post the output here (please obscure any token or you can also email me mailto:github@sensenet.nu if you prefer)

curl http://localhost:32400/livetv?X-Plex-Token= curl http://localhost:32400/livetv/dvrs?X-Plex-Token= From the output of the last one, I'm guessing there should be some kind of unique identifier for each DVR you have, go through each one (if more than one) and issue the following command:

curl http://localhost:32400/?X-Plex-Token= (if the command fails, you've probably got the wrong id, so make sure to test with all available ids)

Once you've done all this, please stop the recording and redo the same steps again (so we can compare differences).

This should give us a very good starting point and hopefully should be able to implement the DVR detection.

If you want, you can email me mailto:github@sensenet.nu and I'll invite you to the slack channel and we can chat directly. But regardless, if you do the above steps, we should be fine πŸ˜„

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/mrworf/plexupdate/issues/177#issuecomment-290146097, or mute the thread https://github.com/notifications/unsubscribe-auth/AZS_qva6KGv4Y5oT1n3YRLn5_TVA_j9lks5rqodlgaJpZM4Mhybw.

mrworf commented 7 years ago

From all the commands please.

Thanks ☺️

On Apr 6, 2017, 8:23 AM, at 8:23 AM, neo-17 notifications@github.com wrote:

Ok, thanks. I will run those tests and post the output. Do you need the output from all the commands or just the last one?

On Mar 29, 2017, at 12:31 PM, Henric Andersson notifications@github.com wrote:

Here's what we need:

First, login to your plex server and get the PlexOnlineToken from "/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Preferences.xml" ... It's the field called "PlexOnlineToken"

Next, while you're still logged in, initiate a recording on Plex and then issue the following commands and post the output here (please obscure any token or you can also email me mailto:github@sensenet.nu if you prefer)

curl http://localhost:32400/livetv?X-Plex-Token=<insert token here without quotes> curl http://localhost:32400/livetv/dvrs?X-Plex-Token=<insert token here without quotes> From the output of the last one, I'm guessing there should be some kind of unique identifier for each DVR you have, go through each one (if more than one) and issue the following command:

curl http://localhost:32400/?X-Plex-Token=<insert token here without quotes> (if the command fails, you've probably got the wrong id, so make sure to test with all available ids)

Once you've done all this, please stop the recording and redo the same steps again (so we can compare differences).

This should give us a very good starting point and hopefully should be able to implement the DVR detection.

If you want, you can email me mailto:github@sensenet.nu and I'll invite you to the slack channel and we can chat directly. But regardless, if you do the above steps, we should be fine πŸ˜„

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/mrworf/plexupdate/issues/177#issuecomment-290146097, or mute the thread https://github.com/notifications/unsubscribe-auth/AZS_qva6KGv4Y5oT1n3YRLn5_TVA_j9lks5rqodlgaJpZM4Mhybw.

-- You are receiving this because you commented. Reply to this email directly or view it on GitHub: https://github.com/mrworf/plexupdate/issues/177#issuecomment-292208388

tonyrayo commented 7 years ago

Do you think SiliconDust or Plex would offer a refurbished unit for development purposes? There are about 5 projects (not including this enhancement) that I would like to add/enhance to that make use of Plex DVR in some respect (in the case of Connect or Extend units I am situated in an ideal location that would allow me to capture broadcast television from both the Washington D.C. and Baltimore areas; or if given access to a Prime, I would rent a CableCard). A rental period of 1 month would be sufficient to cover all projects (based on past experiences 2 - 3 weeks would be enough so that includes an extra buffer of time).

If you are aware of any other open-source projects (GitHub hosted preferred) that could benefit from having the listed hardware tested, please let me know. Thanks for your efforts regarding this extremely handy application/tool!

mrworf commented 7 years ago

No idea to be honest. But you can always ask. I was hoping @neo-17 would get back with details from his testing soon as we could move to implementation :)

arkestlerdev commented 7 years ago

Sorry for the delay, I am currently recovering from a catastrophic drive failure. I will get the tests done as soon as I can. Again, my apologies.

mrworf commented 7 years ago

No worries, sorry to hear that. I hope you can recover any critical data you might have on the drives.

cdanderson commented 7 years ago

@mrworf,

I was curious about this topic and found this issue and thought I could help out in the interim.

While not recording:

curl http://localhost:32400/livetv

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="2" content="plugins">
<Directory key="dvrs" title="dvrs" />
<Directory key="epg" title="epg" />
</MediaContainer>

curl http://localhost:32400/livetv/dvrs

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="1">
<Dvr key="2" uuid="3fe36777-94dc-4406-a168-2bdd73b174b3" language="eng" lineup="lineup://tv.plex.providers.epg.onconnect/USA-OTA14534#Local%20Over%20the%20Air%20Broadcast" lineupTitle="Local Over the Air Broadcast" refreshedAt="1495445343" epgIdentifier="tv.plex.providers.epg.onconnect:2">
<Device parentID="2" key="1" uuid="device://tv.plex.grabbers.hdhomerun/1047A119" uri="http://192.168.13.65:80" protocol="livetv" status="alive" state="enabled" lastSeenAt="1495029404" canTranscode="0" deviceAuth="OTFoGXCbj7W1TtztChOGMoP6" make="Silicondust" model="HDHomeRun CONNECT" modelNumber="HDHR4-2US" source="0" sources="0,1" thumb="/:/resources/dvr/device-hdhomerun-connect-560.png" tuners="2">
<ChannelMapping deviceIdentifier="8.1" enabled="1" lineupIdentifier="8.1" />
<ChannelMapping deviceIdentifier="8.2" enabled="1" lineupIdentifier="8.2" />
<ChannelMapping deviceIdentifier="8.3" enabled="1" lineupIdentifier="8.3" />
<ChannelMapping deviceIdentifier="8.4" enabled="1" lineupIdentifier="8.4" />
<ChannelMapping deviceIdentifier="13.1" enabled="1" lineupIdentifier="13.1" />
<ChannelMapping deviceIdentifier="13.2" enabled="1" lineupIdentifier="13.2" />
<ChannelMapping deviceIdentifier="13.3" enabled="1" lineupIdentifier="13.3" />
<ChannelMapping deviceIdentifier="21.1" enabled="1" lineupIdentifier="21.1" />
<ChannelMapping deviceIdentifier="21.2" enabled="1" lineupIdentifier="21.2" />
<ChannelMapping deviceIdentifier="21.3" enabled="1" lineupIdentifier="21.3" />
<ChannelMapping deviceIdentifier="21.4" enabled="1" lineupIdentifier="21.4" />
<ChannelMapping deviceIdentifier="31.1" enabled="1" lineupIdentifier="31.1" />
<ChannelMapping deviceIdentifier="31.2" enabled="1" lineupIdentifier="31.2" />
<ChannelMapping deviceIdentifier="31.3" enabled="1" lineupIdentifier="31.3" />
<ChannelMapping deviceIdentifier="31.4" enabled="1" lineupIdentifier="31.4" />
<ChannelMapping deviceIdentifier="42.1" enabled="1" lineupIdentifier="42.1" />
<ChannelMapping deviceIdentifier="42.2" enabled="1" lineupIdentifier="42.2" />
<ChannelMapping deviceIdentifier="46.1" enabled="1" lineupIdentifier="46.1" />
<ChannelMapping deviceIdentifier="46.2" enabled="1" lineupIdentifier="46.2" />
<ChannelMapping deviceIdentifier="46.3" enabled="1" lineupIdentifier="46.3" />
<ChannelMapping deviceIdentifier="46.4" enabled="1" lineupIdentifier="46.4" />
<ChannelMapping deviceIdentifier="46.5" enabled="1" lineupIdentifier="46.5" />
<ChannelMapping deviceIdentifier="46.6" enabled="1" lineupIdentifier="46.6" />
<ChannelMapping deviceIdentifier="51.1" enabled="1" lineupIdentifier="51.1" />
<ChannelMapping deviceIdentifier="51.2" enabled="1" lineupIdentifier="51.2" />
<ChannelMapping deviceIdentifier="51.3" enabled="1" lineupIdentifier="51.3" />
<ChannelMapping deviceIdentifier="51.4" enabled="1" lineupIdentifier="51.4" />
<ChannelMapping deviceIdentifier="51.5" enabled="1" lineupIdentifier="51.5" />
<ChannelMapping deviceIdentifier="51.6" enabled="1" lineupIdentifier="51.6" />
<Setting id="transcodeDuringRecord" label="Convert video while recording" default="0" summary="[Experimental] This can save disk space and improve compatibility. Converting requires a fast CPU." type="int" value="0" hidden="0" advanced="0" group="" enumValues="0:Off|1:Remux Only|2:Transcode" />
</Device>
<Setting id="startOffsetMinutes" label="Minutes before start" default="0" summary="The default duration to record before the scheduled time." type="int" value="0" hidden="0" advanced="0" group="" />
<Setting id="endOffsetMinutes" label="Minutes after end" default="0" summary="The default duration to record after the scheduled time." type="int" value="0" hidden="0" advanced="0" group="" />
<Setting id="useUmp" label="Enhanced Program Guide" default="false" summary="When enabled, richer information is downloaded for some shows and movies. This makes guide refreshing slower." type="bool" value="true" hidden="0" advanced="0" group="" />
<Setting id="postprocessingScript" label="Postprocessing script" default="" summary="Full path to a program which postprocesses the recording before adding to the library." type="text" value="" hidden="0" advanced="0" group="" />
</Dvr>
</MediaContainer>

While recording: I tried making the following requests: http://localhost:32400/2 http://localhost:32400/3fe36777-94dc-4406-a168-2bdd73b174b3 http://localhost:32400/1

and received this response:

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="0" content="plugins">
</MediaContainer>

I've confirmed I'm recording so I would expect to see something there, so I tried passing the device UUID and device URI as the key, but just received a 404. Any ideas on anything else I should try?

demonbane commented 7 years ago

@cdanderson These were suggested from the forums, so let's see if either of them is helpful:

http://localhost:32400/media/subscriptions/scheduled http://localhost:32400/tuners.html

If you can try them both when something is being recorded and when nothing is recording that would be great.

tonyrayo commented 7 years ago

Progress! 😞 sorry about the drive(s) imploding on you though @neo-17

mrworf commented 7 years ago

@cdanderson any update?

gharris012 commented 7 years ago

I scheduled a few recordings and captured /media/subscriptions/scheduled during the recordings and after they were complete.

Note that /tuners.html from the forum post you mentioned is for the HDHR tuner itself (not from Plex), so I did not include that. While you could get the URL for the HDHR from /livetv/dvrs the tuner could be in use by something other than Plex.

At any rate, looking through scheduled-inprogress, you will see 'status="inprogress"' for the current recordings. They are mentioned many, many times as the conflicting recordings for other shows that are currently airing - I assume that is a bug since none of those shows are actually scheduled to record - but if you strip out or ignore all the sections, then grep for inprogress you will (more easily) see the three current recordings.

scheduled-inprogress.txt scheduled-noprogress.txt

mrworf commented 6 years ago

Thanks, will look into implementing a test for this later this week

kyse commented 6 years ago

Hey guys, regarding the plex update checking if there's any current activity... I've recently been testing hw trancoding, so not sure if this is a problem specific to that, but i notice when users have left a video paused, it stays in the activity as a paused transcoding session. This ends up preventing the update from happening. Would be nice to have a flag to ignore paused activity.

m1lkman commented 6 years ago

I was doing some testing with PowerShell and found that the below URL returned an xml array named "Video" that if it contained any integers then either Live TV or DVR was running. The integer value being the number of active sessions. Just thought I'd share.

http://localhost:32400/livetv/sessions?X-Plex-Token=<insert token here without quotes>

Thanks for all your hard work on this update script.

demonbane commented 6 years ago

Since neither @mrworf nor I have a tuner to test with, can anyone else test @m1lkman's suggestion from above and verify that it does provide the expected result? That looks like a pretty easy test to add, I just want to make sure that it's reliable across a few different setups before we push it out.

kyse commented 6 years ago

Nothing playing:

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="0">
</MediaContainer>

Live Streaming:

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="1">
  <Video type="clip" title="Live Session " summary="" index="1" ratingCount="0" 
    genuineMediaAnalysis="1" key="/livetv/sessions/e782fd9c-898d-47fb-9b0e-0a9df4f7126c" live="1">
    <Media videoResolution="480" width="640" height="480" aspectRatio="1.33" audioChannels="2" 
      audioCodec="ac3" videoCodec="mpeg2video" container="mpegts" origin="livetv" protocol="hls" 
      uuid="e782fd9c-898d-47fb-9b0e-0a9df4f7126c">
      <Part size="0" container="mpegts" protocol="hls">
        <Stream streamType="1" codec="mpeg2video" index="0" closedCaptions="1" frameRate="29.970" 
          height="480" level="8" pixelAspectRatio="1:1" profile="main" scanType="interlaced" width="640" />
        <Stream streamType="2" selected="1" codec="ac3" index="1" channels="2" bitrate="128" 
          language="English" languageCode="eng" audioChannelLayout="stereo" samplingRate="48000" />
      </Part>
      <TranscodeSession key="/transcode/sessions/e782fd9c-898d-47fb-9b0e-0a9df4f7126c" throttled="0" 
        complete="0" progress="-1" speed="6.5" duration="7200000" remaining="0" context="static" 
        sourceVideoCodec="" sourceAudioCodec="" videoDecision="copy" audioDecision="copy" 
        protocol="hls" container="mpegts" videoCodec="*" audioCodec="*" audioChannels="2" 
        transcodeHwRequested="0" />
    </Media>
  </Video>
</MediaContainer>

DVR Active:

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="1">
  <Video type="clip" title="Live Session " summary="" index="1" ratingCount="0" 
    genuineMediaAnalysis="1" key="/livetv/sessions/bca7d635-1d3c-4475-8641-a6b571ef544f" live="1">
    <Media videoResolution="720" width="1280" height="720" aspectRatio="1.78" audioChannels="6" 
      audioCodec="ac3" videoCodec="mpeg2video" container="mpegts" origin="livetv" protocol="hls" 
      uuid="bca7d635-1d3c-4475-8641-a6b571ef544f">
      <Part size="0" container="mpegts" protocol="hls">
        <Stream streamType="1" codec="mpeg2video" index="0" closedCaptions="1" frameRate="59.940" 
          height="720" level="4" pixelAspectRatio="1:1" profile="main" scanType="interlaced"
          width="1280" />
        <Stream streamType="2" selected="1" codec="ac3" index="1" channels="6" bitrate="384" 
          language="English" languageCode="eng" audioChannelLayout="5.1(side)" samplingRate="48000" />
        <Stream streamType="2" codec="ac3" index="2" channels="1" bitrate="96" 
          language="Espa&#241;ol" languageCode="spa" audioChannelLayout="mono" 
          samplingRate="48000" />
      </Part>
      <TranscodeSession key="/transcode/sessions/bca7d635-1d3c-4475-8641-a6b571ef544f" 
        throttled="0" complete="0" progress="-1" speed="1.2999999523162842" duration="7200000" 
        context="static" sourceVideoCodec="" sourceAudioCodec="" videoDecision="copy" 
        audioDecision="copy" protocol="hls" container="mpegts" videoCodec="*" audioCodec="*" 
        audioChannels="2" transcodeHwRequested="0" timeStamp="1518161679.2866521" 
        maxOffsetAvailable="22.395644000000001" minOffsetAvailable="1" />
    </Media>
  </Video>
</MediaContainer>

And as a bonus, for taking the time to offer this up, perhaps someone could save me some time... I keep getting situations where someone has left a playback in a paused state. Can we add a flag to proceed with the update if all active sessions are in a paused state. Removed the unimportant stuff, just showing the tree to climb to get to the paused state attribute for someone to write up an xpath query.

<?xml version="1.0" encoding="UTF-8"?>
<MediaContainer size="1">
  <Video>
    <Player state="paused"/>
  </Video>
</MediaContainer>

PS: I think this will take care of the main part of the logic, but might need to edit some stuff to add allow using a flag to toggle this functionality:

In plexupdate-core line 201, where it returns 0, change that to:

echo "${DATA}" | grep -q -e '<Player[^>]*state="playing".*'
if [ $? -eq 1 ]; then
  return 1
fi
return 0
demonbane commented 6 years ago

@kyse is the Player element from a different endpoint than /livetv/sessions? I'm not seeing it in the sample output for the two examples you gave.

kyse commented 6 years ago

Yes, I'm discussing two topics, all related to the title of this ticket. If that's undesirable I blame the title of this thread being too broad.

The 1st three blocks I posted are related to what you requested, ie DVR and live tv in-use checks.

The 4th, is related to standard playback in-use check, and more specifically if a playback is actually active, or just paused for like 20 hours holding up an auto update, and is related to the /status/sessions api call found in the running method in plexupdate-core.

demonbane commented 6 years ago

No problem with discussing multiple topics, I just need to know which endpoints you're talking about to be able to implement the tests. :)

I'm working on the livetv/dvr bit right now. I'll take a look at the paused status bit right after that.

kyse commented 6 years ago

Yes sir, np. Let me know if I can offer further assistance to help advance this.

demonbane commented 6 years ago

Ok, I have preliminary support for both checking for live TV/DVR streams as well as ignoring currently paused streams ready to go. I didn't add it as an option, since a paused stream can be resumed even if the server restarts while it's paused. (assuming the connection doesn't get dropped completely)

Since this is a pretty big change (in a small amount of code), I'd love to get some real world testing done before pushing this out to everyone.

For anyone that can help test this, you can install this version by running the following from within your plexupdate directory

BRANCHNAME=in-use-check ./plexupdate.sh -uf

(If you installed plexupdate as root, you may need to add "sudo" to the beginning of that command)

This will download the testing version and run a "forced" update. That way even if you have the latest version, the update will still be attempted so that we can see if the in use checking is actually working.

Please try to test it with as many different combinations as possible. e.g. Watching live TV on one player while streaming a saved movie on another, etc.

To go back to the regular release, just type git reset --hard origin/master (see note about sudo above). Note that if you run plexupdate without the "BRANCHNAME" before it, you'll get into an infinite update loop. If that happens, just add the "BRANCHNAME" part again or run plexupdate with '-U' temporarily.

kyse commented 6 years ago

Checked against local client, and someone remotely in play & pause state + live tv and dvr recording. Everything appears to be working properly.

demonbane commented 6 years ago

If I would have waited 11 more days, it would have been exactly 1 year since this issue was opened... :)

This has now been merged and is available for everyone. Thanks to everyone that contributed.