Jump to content

AutoCompress, run CCExtractor, Comskip and Archive AFTER watching a recorded TV episode


muzicman0

Recommended Posts

muzicman0

First and foremost, I want to thank Luke and PenkethBoy from this forum for a ton of help (oh, and an honorable mention to Google!).  If anyone finds errors, or missing info, please reply to this thread, and I will edit appropriately. 

 

I have been working on a couple scripts to automate some processes in my Home Theater, and I wanted to share what I have created.  This thread is specifically to do the following:

  1. Use FFMPEG to transcode a recorded TV episode, but ONLY after watching it, and ONLY shows that I have pre-determined that I want to keep.
    1. It will write to a new location.
    2. The filename will be something like Bull - S01E02 - Episode Name.mp4
    3. The path will be \Series Name\Season #\Filename
  2. As of v 2.0, Closed captions and Comskip will be extracted
  3. Delete the original file as long as no errors were returned by FFMPEG (IE: the transcoding was a success).

I know this post is SUPER long, but if you like automation as much as I do, this may help you get started!  I will be sharing another script in another post soon on how to auto create EDL files for automatic commercial skipping, and how to use KODI as a front end on either a PC or Nvidia Shield to make it work.  I didn't want to use the post processing built in to Emby because Nvidia soft limits your encoding sessions to 2 encodes at a time, and there are times where I am recording more than that, AND I didn't want it to interfere with current recordings or streaming sessions that were in progress.  This allows me to use the Windows Task Scheduler.

 

Here are a few things about my setup.  First, this is done in Windows.  I record TV episodes to a library called ‘Recorded TV’, and I have a separate library called ‘TV Shows’.  The latter being shows that I have gotten from DVD or Blu-Ray rips, or in this case, shows that I have already watched that I want to keep for possible future watching.  It would take a lot of disk space to just keep the shows in their native format, so transcoding was needed.  I used to transcode to 854x480 h.264, but just recently, I got a new Nvidia GPU, and the HEVC encoding on the newer gen cards (RTX, or GTX 1660) is so much better than it used to be, I decided to keep the videos in their native resolution/frame rate and use h.265 (HEVC) to compress.  This results in a very good quality video, with anywhere from 50-75% space savings.  I still haven’t figured out how to include Closed Captions in the encoded video, so if anyone knows…or really any suggestions that would help make this better, I am all ears.  Since I am using Nvidia NVENC with FFMPEG, it does require the use of a modern Nvidia GPU unless you modify the VBS script appropriately.  You will probably also want to install the latest driver from Nvidia.

 

You also need to understand that I am not a programmer/scripter, so I have no doubt that this code may not be optimized, or perfect, but I will say it works well for me, and I am pretty sure that I have gotten most of the corner cases taken care of, but there are no guarantees that it will work for you.  I am in the US, and NO testing has been done by anyone other than me.  I am not responsible for any file loss or damage if it occurs.

 

OK, so here we go…I hope this is helpful to someone!

 

First thing is there are 2 scripts.  I’m sure this could be done in 1, but I am mostly adept at VBS, but to actually get a list of episodes was easier in a PowerShell script.  If you create a document in Notepad (or, like myself, NotePad++), and save it as “Emby_Find WatchedEpisodes.ps1” as the filename.  Or whatever you want to name it as long as it has the .ps1 extension.  Paste the following code into the file, and change the username and password to the appropriate values.  This is designed to be run on the actual Emby Server PC, but it could probably be modified to run on a different PC if needed.  If you are not running the script on the Emby Server, simply change the $embyServerURL variable to the correct IP address/port.

$embyServerUrl = "http://127.0.0.1:8096"
$BasePath = "O:\OneDrive - Personal\AutoCompress\TVEpisode.csv"
$Emby_User_Name = "xxxxxxx"
$Emby_User_Pwd = 'xxxxxxx' # if you dont have a password leave as ''


Function Get-StringHash([String] $String,$HashName = "MD5") 
{ 
    $StringBuilder = New-Object System.Text.StringBuilder 
    [System.Security.Cryptography.HashAlgorithm]::Create($HashName).ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))|ForEach-Object{ 
        [Void]$StringBuilder.Append($_.ToString("x2")) 
    } 
    $StringBuilder.ToString() 
}


$embyClientName = "PS-Find Watched Episodes"
$embyDeviceName = "PowerShell"
$embyDeviceId = "7"
$embyApplicationVersion = " - 1.0.0"


Function Get-EmbyAccessToken ($Username, $Pwd)
{
    $authUrl = "{0}/Users/AuthenticateByName?format=json" -f $embyServerUrl
    $sha1Pass = Get-StringHash -String $Pwd -HashName "SHA1"
    $md5Pass = Get-StringHash -String $Pwd -HashName "MD5"
    $postParams = (@{Username="$username";pw=$Pwd;password="$sha1Pass";passwordMd5="$md5Pass"} | ConvertTo-Json)
    $headers = @{"Authorization"="Emby Client=`"$embyClientName`", Device=`"$embyDeviceName`", DeviceId=`"$embyDeviceId`", Version=`"$embyApplicationVersion`""}


    Write-Verbose ("authUrl={0},Username={1},sha1Pass={2},md5Pass={3},params={4}" -f $authUrl, $Username,$sha1Pass,$md5Pass,$postParams)
    return (Invoke-WebRequest -Uri $authUrl -Method POST -Body $postParams -ContentType "application/json" -Headers $headers)
} 


$authResult = Get-EmbyAccessToken -Username $Emby_User_Name -Pwd $Emby_User_Pwd
$user = $authResult.Content | ConvertFrom-Json


$MediaUrl = $embyServerUrl + "/emby/users/" + $User.User.Id + "/items?Fields=width,height,Path&Recursive=true&IncludeItemTypes=Episode&IsPlayed=True&IsMissing=False&ParentId=6f25559632c2aca7578b4fdc30acb587&SortBy=IndexNumber&SortOrder=Descending" + "&api_key=" + $User.AccessToken


Invoke-WebRequest -method GET -uri $MediaUrl | ConvertFrom-Json | Select-Object -ExpandProperty  Items | ConvertTo-Csv -NoTypeInformation -Delimiter '^' | Set-Content $BasePath


Exit

You will need to find the following line:

$MediaUrl = $embyServerUrl + "/emby/users/" + $User.User.Id + "/items?Fields=Path&Recursive=true&IncludeItemTypes=Episode&IsPlayed=True&IsMissing=False&ParentId=6f25559632c2aca7578b4fdc30acb587" + "&api_key=" + $User.AccessToken

And change the “6f25559632c2aca7578b4fdc30acb587” part to match your recorded TV library.  The way you find your ‘parentid’ is to navigate within the Emby webapp to the library (simply click on the Library within the ‘MyMedia’ heading.  Once you are there, look at the URL in your web browser, and find the part the says ‘parentid=’ and then a string of characters.  This string of characters is what you want to replace “6f25559632c2aca7578b4fdc30acb587” with. 

 

You will also need to change the $BasePath variable to whatever suits your needs.  I have this set up so that all the scripts are run from the same folder.  Most likely you would want this variable to be the same directory where you saved the PowerShell script.

 

Once the above changes have been made, save the file and set aside.

 

What the above does is use the Emby API to return a list of episodes in a CSV formatted file that meet the following criteria:

  1. Is a TV Episode (IE: not a movie)
  2. Is ‘played’ (IE: you have watched it)
  3. Is actually on the disk
  4. Is in your recorded TV library

In order to get this script to run, you may need to change your PowerShell Execution Policy (Google is your friend here!).  If you run the file on your library now, it may or may not return any episodes, but it should write a file that you can take a look at in either Excel, or NotePad++.

 

Now that you have a list of episodes that need compressed, we need a way to automatically compress them without intervention on our side.  As I mentioned earlier, I am way more comfy with VBS scripting, so this script is in VBS, you can create it the same way as the PowerShell script, but instead of the .ps1 file extension, use .vbs.  I named mine “Emby_CompressWatchedEpisodes.vbs”

 

Here is the VBS code:

rem version 2.0.0
Const ForReading = 1
Const ForAppending = 8


MaxLogLength = 500 'Maximum number of lines in the log before being archived
bTranscode = true 'change to false if you don't want transcoding
bClosedCaptions = true 'change to false if you don't want a seperate file for subtitles
bComskip = true 'change to false if you don't want an edl file for comskip


BasePath = "O:\OneDrive - Personal\AutoCompress\"   'The folder where this script and FFMPEG.EXE is located
RecordedTVPath = "\\10.1.0.130\Local Cloud\OneDrive\Recorded TV\"   'Change this to your Recorded TV path
ArchivedTVPath = "T:\TV\"
LogFile = BasePath & "SCW-Compress Episodes Log.log"
CSVDateModified = ShowFileAccessInfo(BasePath & "TVEpisode.csv")


Set WshShell = CreateObject("WScript.Shell") 
Set objFSO = CreateObject("Scripting.FileSystemObject")
    
    'If log file is > MaxLogLength lines, rename, and recreate
    If objFSO.FileExists(LogFile) Then
        strData = objFSO.OpenTextFile(LogFile,ForReading).ReadAll


        'Split by lines, put into an array
        arrLines = Split(strData,chr(13))


        'Use UBound to count the lines
        LineCount = UBound(arrLines) + 1


        if LineCount > MaxLogLength then
        CreateFolder BasePath & "Archived Logs\"
            strMoveTo = BasePath & "Archived Logs\" & strClean(now (), false) & ".SCW-Compress Episodes Log.log"
            MoveFile LogFile, strMoveTo
        end if
    end if


If not objFSO.FileExists(LogFile) Then   'Create, or open the log file
    Set objLogFile = objFSO.CreateTextFile(LogFile, True)
Else
    Set objLogFile = objFSO.OpenTextFile(LogFile, ForAppending)
End If


objLogFile.Write Now() & ": Application Started." & chr(13)


    if CSVDateModified = FormatDateTime(now(), 2) then
        Set objFile = objFSO.OpenTextFile(BasePath & "TVEpisode.csv", ForReading)   'The CSV created with the PowerShell script
    Else 
        objLogFile.Write Now() & ": INFO!! - Date Modified on TVEpisode.csv has not been updated, exiting application." & chr(13)
        objLogFile.Write Now() & ": Application Finished." & chr(13) & chr(13)
        objLogFile.Close
        WScript.Quit
    end if


FirstTime = True
NameExists = false
Do While objFile.AtEndOfStream <> True
    
    arr = Split(objFile.ReadLine, "^")  'I used the '^' in the CSV as the delimiter since using the traditional commas caused issues
    
    if FirstTime = true then   'Seems the format of the CSV file can change, so I am mapping index #'s to variables
        FirstTime = False
        For nIndex = 0 to uBound(arr)
            tmpString = mid(arr(nIndex), 2, len(arr(nIndex)) - 2)
            Select Case tmpString
                Case "SeriesName"
                    indSeries = nIndex
                Case "SeasonName"
                    indSeason = nIndex
                Case "IndexNumber"
                    indEpisode = nIndex
                Case "Path"
                    indPath = nIndex
                Case "Width"
                    indWidth = nIndex
                Case "Height"
                    indHeight = nIndex
                Case "Name"
                    indName = nIndex
                    NameExists = True
            End Select
        Next
    end if
    strPath = arr(indPath)
    strSeries = mid(arr(indSeries), 2, len(arr(indSeries)) - 2)
    
    Set RE = New RegExp
    RE.IgnoreCase = True
    RE.Pattern = "s\d\de\d\d"
    set matches = re.execute(strPath)
  
    If RE.Test(strPath) Then 
        reSnEp = matches.item(0)
        strSeason = mid(reSnEp, 2, 2)
        strEpisode = right(reSnEp, 2)
    else
        strSeason = "00"
        strEpisode = "Unknown"
    End If
    
    strName = mid(arr(indName), 2, len(arr(indName)) - 2)


    If NameExists = True then
        if uCase(right(strPath, 3)) = "TS" & chr(34) then    'ONLY compress TS files (which means it was actually recorded, and not downloaded)
            ShouldCompress = FileCompare(strSeries)
                if ShouldCompress = True then
                    strHeight = mid(arr(indHeight), 2, len(arr(indHeight)) - 2)
                          '2 Megabit for 1280x720, 4 Megabit for all others. NO LONGER USED
                          if strHeight = "720" then
                            strBitrate = "3M"
                          Else
                            strBitrate = "4M"
                          End If


                    Set oWS = CreateObject("WScript.Shell")
                    oPathCheck = ArchivedTVPath & strClean(strSeries, False) & "\Season " & strSeason & "\"
                    oPath = chr(34) & ArchivedTVPath & strClean(strSeries, False) & "\Season " & strSeason & "\" & strClean(strSeries, True) & " - S" & strSeason & "E" &strEpisode & " - " & strClean(strName, False) & ".mp4" & chr(34)
                    ccPath = chr(34) & BasePath & "CCExtractor\ccextractorwin.exe" & chr(34) & " -delay -10000 " & strPath & " -o " & left(oPath, len(oPath) - 4) & "srt" & chr(34)  '-10000 compensates for the 10 seconds removed in FFMPEG
                    trPath = chr(34) & BasePath & "ffmpeg.exe" & chr(34) & " -ss 00:00:10 -y -i " & strPath & " -vf yadif=0:-1:0 -c:v hevc_nvenc -rc:v constqp -qp 23 -preset slow -rc-lookahead 32 -g 600 -c:a copy " & oPath 
                    csPath = chr(34) & BasePath & "Comskip\comskip.exe" & chr(34) & " " & oPath
                    
                    CreateFolder oPathCheck
                    if bClosedCaptions = true and bTranscode = true then ccErrCode = oWS.run(ccPath,,True) 'comment out this line if you don't want to extract Closed Captions
                    if bTranscode = true then trErrCode = oWS.Run(trPath,,True)  'value of true will wait for completion, and return an error code
                    if bComskip = true then csErrCode = oWS.Run(csPath,,True)  'value of true will wait for completion, and return an error code
                    
                    if trErrCode = 0 and bTranscode = true then
                        strTempFileName = mid(arr(indPath), 2, len(arr(indPath)) - 2)
                        DeleteFile strTempFileName
                        DeleteFile left(strTempFileName, len(strTempFileName) - 2) & "edl"
                        DeleteFile left(strTempFileName, len(strTempFileName) - 2) & "jpg"
                        DeleteFile left(strTempFileName, len(strTempFileName) - 2) & "nfo"
                        objLogFile.Write Now() & ": SUCCESS!! - FFMPEG (" & strSeries & "): " & trPath & chr(13)
                        objLogFile.Write Now() & ": The original file was compressed and deleted." & chr(13)
                    else
                        objLogFile.Write Now() & ": ERROR!! - Compression on " & strPath & " failed (ffmpeg error code was: " & trErrCode & "), and deletion was aborted." & chr(13)
                        objLogFile.Write Now() & ": ERROR!! - FFMPEG (" & strSeries & "): " & trPath & chr(13)
                    end if
                    
                    if ccErrCode = 0 and bClosedCaptions = true then
                        objLogFile.Write Now() & ": SUCCESS!! - Closed Captions (" & strSeries & "): " & ccPath & chr(13)
                    else    
                        if bClosedCaptions = true then objLogFile.Write Now() & ": ERROR!! - Closed Captions failed with error code " & ccErrCode & ": " & ccPath & chr(13)
                    end if
                    
                    if (csErrCode = 0 or csErrCode = 1) and bComskip = true then
                        objLogFile.Write Now() & ": SUCCESS!! - Comskip (" & strSeries & "): " & csPath & chr(13)
                    else
                        if bComskip = true then objLogFile.Write Now() & ": ERROR!! - Comskip failed with error code " & csErrCode & ": " & csPath & chr(13)
                    end if
                    
                    trErrCode = 1
                    ccErrCode = 1
                    csErrCode = 2
                Else
                    objLogFile.Write Now() & ": INFO!! - Compression on " & strSeries & " was skipped since it was not in the AutoCompressList.txt file." & chr(13)
                End If
        Else
            if strSeries <> "SeriesName" then
            
                for nIndex = 1 to 5   'find out how long the file extension is by findign the last '.' in the path
                    if mid(strPath, len(strPath) - nIndex, 1) = "." then 
                        iIndex = nIndex
                        Exit For
                    End If
                next
        
                objLogFile.Write Now() & ": INFO!! - Compression on " & strSeries & " was skipped since it was not a .ts file, which means it was likely not recorded." & chr(13)
                ShouldCompress = FileCompare(strSeries)
                if ShouldCompress = True then    'If not a TS file, but it is watched and archived, go ahead and move it.
                    oPathCheck = ArchivedTVPath & strClean(strSeries, False) & "\Season " & strSeason & "\"
                    oPath = ArchivedTVPath & strClean(strSeries, False) & "\Season " & strSeason & "\" & strClean(strSeries, True) & " - S" & strSeason & "E" &strEpisode & " - " & strClean(strName, False) & mid(strPath, len(strPath) - iIndex, iIndex)
                    CreateFolder oPathCheck
                    strPath = mid(strPath, 2, len(strPath) - 2)             
                    MoveFile strPath, oPath
                    objLogFile.Write Now() & ": INFO!! - " & strSeries & " - S" & strSeason & "E" & strEpisode & " was moved to " & oPath & "." & chr(13)
                    DeleteFile left(strPath, len(strPath) - iIndex) & ".nfo"
                    DeleteFile left(strPath, len(strPath) - iIndex) & ".edl"
                    DeleteFile left(strPath, len(strPath) - iIndex) & ".jpg"
                End If
            End If
        End If
    Else 
        objLogFile.Write Now() & ": WARNING - Compression on " & strSeries & " was skipped since the Name property did not exist, and could result in an overwrite." & chr(13)
    End If    
Loop
objLogFile.Write Now() & ": Application Finished." & chr(13) & chr(13)
objLogFile.Close
    
'------------------------------------------------------------
'DO NOT CHANGE THE BELOW CODE!!!!!


Function FileCompare(strShowName)
    FileCompare = False
    filename = BasePath & "AutoCompressList.txt"


    Set fso = CreateObject("Scripting.FileSystemObject")
    Set f = fso.OpenTextFile(filename)


    Do Until f.AtEndOfStream
        tempfilename = f.ReadLine
        if left(strShowName, len(tempfilename)) = tempfilename then FileCompare = True
    Loop


    f.Close
    Set fso = Nothing
End Function


Function CreateFolder(strPathToFolder)
    Set oShell = WScript.CreateObject ("WScript.Shell")
    oShell.run "cmd.exe /c if not exist " & chr(34) & strPathToFolder & chr(34) & " mkdir " & chr(34) & strPathToFolder & chr(34)
    Set oShell = Nothing
End Function


Function DeleteFile(strPathToFile)
    Set oShell = WScript.CreateObject ("WScript.Shell")
    oShell.run "cmd.exe /c del " & chr(34) & strPathToFile & chr(34)
    Set oShell = Nothing
End Function


Function strClean (strtoclean, bSeries)
    tempstr = strtoclean
    charArray = Array("?", "/", ":", "*", """", "<", ">", "|", "/")


    For Each tmpChar in charArray


        Select Case tmpChar
        Case ":"
        changeTo = "_"
        Case """"
        changeTo = ""
        Case Else
        changeTo = " "
        End Select


        tempstr = replace( tempstr, tmpChar, changeTo )
    Next
  
    if bSeries = False then
        if right(tempstr, 3) = "..." then
            strClean = tempstr & "_"
        elseif right(tempstr, 1) = "." then
            strClean = left(tempstr, len(tempstr) - 1)
        else strClean = tempstr
        end if
    else
        strClean = tempstr
    end if
End Function


Function MoveFile (strPath2, strDestination)
    Set FSO=CreateObject("Scripting.FileSystemObject")
        FSO.MoveFile strPath2, strDestination
    Set FSO=Nothing
End Function


Function ShowFileAccessInfo(filepath)
   Set fso = CreateObject("Scripting.FileSystemObject")
   Set f = fso.GetFile(filepath)
   ShowFileAccessInfo = FormatDateTime(f.DateLastModified, 2)
   set fso=Nothing
End Function

You will need to change all three path variables to appropriate values.

 

  1. BasePath should be the same $BasePath as the PowerShell script, and should probably be where the script resides
  2. RecordedTVPath should be the path to your recorded TV files.
  3. ArchivedTVPath should be where you want to save the transcoded files.

 

That should be all that is needed to be changed for this script, so save it as a VBS file and set it aside.

 

OK, the last couple details are what needs to be in the folder with the scripts.  Below is a list of files that should be included in your ‘BasePath’ directory (again, where these scripts are located).

  1. FFMPEG should be here.  You can download a pre-compiled version and just copy ffmpeg.exe to this folder.
  2. You should have a ‘AutoCompressList.txt’ text file in this directory as well.  This is simply a list of Series that you want to auto compress.
    1. 1 series per line
    2. The script will do a simple comparison, and the way I have it set up, if you have Marvel’s in the file, ANY series that begins with Marvel’s will be a match.
    3. If you have Marvel's Agent in the file, then Marvel's Cloak will NOT be a match.
  3. You should run the PowerShell script before the VBS script, so there should be a TVEpisode.csv file in this folder as well.
  4. A log file will also be created at run time.
  5. The 2 scripts should also be in this folder.
  6. So, there should be 5 files in this folder (not including the log file that will be created after first run).
  7. As of version 2.0.0, if desired:

           -Create a CCExtractor folder in your BasePath, and put CCExtractor files inside this folder

           -Create a Comskip folder and put Comskip files inside this folder

               *If you don't want CCExtractor or Comskip to run, change the variables on Lines 7 & 8 (subject to change!) to false.

 

Personally, I use Windows Task Scheduler to automate this completely.  The PowerShell script runs at 11:15 PM every night, and the VBS Script runs at 11:30 PM every night.  But there is no reason you can’t run these manually if you choose.  I would suggest backing up a few files first and testing the scripts only on those to make sure everything works for you.

 

Versions:

v2.0.0

   -Lots of Changes to the log file

   -added variable to determine how many log lines before archiving log.  default is 500.

   -Changed default FFMPEG quality to QP based instead of set bit rate.

   -Added:

     -CCExtractor commands to extract Closed Captions

     -Comskip to create an EDL file

     -In order to use the above (Comskip and CCExtractor), a CCExtractor and Comskip folder needs to be created, and the files for the respective components go in these folders.

     -You can turn these off if you don't want them by setting the variables to false on lines 7 & 8 (line #'s could change in future versions).

   -Various bug fixes

v1.5.0 - 03-14-2020

   -Rename the log file with a time stamp once it becomes over 1000 lines.

v1.4.0 - 03-10-2020

   -If the CSV file 'Date Modified' property doesn't match the current date, then the script will exit since there is likely no new information to process.

v1.3.0 - 03-02-2020

   -If the file is marked as watched, and is in the AutoCompressList.txt file, but is NOT a .ts file, it will be moved, but not compressed.

v1.2.0 - 02-22-2020

   -CSV output changed again for an unknown reason.  I am now parsing the season and episode from the path of the file.

   -Added a bit more logging

   -Fixed a bug where a ":" should have been changed in the filename to a "_" but was instead changed to a " ".

   -Removed characters on the String Replace function that would not cause issues.

   -Added a sort order to the powershell script to hopefully get all info each time

 

v1.1.1 - 02-19-2020

   -Fixed bug introduced in last revision where original file would not be deleted

 

v1.1.0 - 02-19-2020

   -It appears that the output columns in the CSV can change order, or content, so I implemented a change that would map the correct column to the variables

 

v1.0.0 - 02-17-2020

   -Initial release

Edited by muzicman0
  • Like 3
Link to comment
Share on other sites

PenkethBoy

Hi

 

Good work :)

 

So these scripts assume the file to be encoded is a TS file as you are only doing recorded tv episodes?

 

Tip:

 

$embyServerUrl = "http://127.0.0.1:8096" for servers on a remote machine this could be the domain url or something like http://192.168.1.100:8096 - so script does not have to be run from the same server as Emby is installed on

 

The other thing i have done is to check the converted file is OK by using ffprobe - and getting it to report on any errors/warnings - then decide if i keep the converted file or park it for review later etc

  • Like 1
Link to comment
Share on other sites

muzicman0

Hi

 

Good work :)

 

So these scripts assume the file to be encoded is a TS file as you are only doing recorded tv episodes?

 

Tip:

 

$embyServerUrl = "http://127.0.0.1:8096" for servers on a remote machine this could be the domain url or something like http://192.168.1.100:8096 - so script does not have to be run from the same server as Emby is installed on

 

The other thing i have done is to check the converted file is OK by using ffprobe - and getting it to report on any errors/warnings - then decide if i keep the converted file or park it for review later etc

On the IP, that I am aware of (I am a network engineer by trade), but I wasn't 100% sure if Emby had any settings that would (by default) restrict API calls from outside the localhost, and I was too lazy to test it, so figured I would leave it alone!

 

The FFProbe is a good idea...will it return an error code of 0 if all is well?

 

Oh, and again, thanks so much for the help.  This (in addition to using EmbyCon and Kodi) has allowed me to shutdown 3 PC's in my home that were basically running 24x7.  I now use the Nvidia Shield on both TV's in the house, and didn't loose any functionality over the JRiver solution I was using.

Link to comment
Share on other sites

PenkethBoy

ffprobe need some params set so it will return useful info

 

e.g. - this is after ffmpeg has finish the convert and finished with no errors - so $newvideo is the mkv file etc

 

(Tip the -f $newvideo puts $newvideo variable in place of {0} - just a formating thing if you have numerous variables to add to a string makes it easier to read)

$ArgumentList2 = '-i "{0}" -loglevel +level -hide_banner -show_streams' -f $newVideo

$FFProbeResult2 = (Start-Process -FilePath $PathFFProbe -ArgumentList $ArgumentList2 -Wait -PassThru -RedirectStandardError "$newVideo.ffprobe.txt" -WindowStyle Hidden)

$FFProbeProblem = Get-ChildItem -Path "$newVideo.ffprobe.txt" | Select-String -Pattern "[warning]","[error]","[fatal]" -SimpleMatch

so depending what you get back in the txt file (which is the output you would see at the command line) your script then acts accordingly on $fprobeproblem - which will be a list of lines from the txt file that match the -pattern

 

beware of error codes in ffmpeg and ffprobe as 0 is ok but anything else is not documented!!! Hence why i do the above

  • Like 1
Link to comment
Share on other sites

muzicman0

I hear you on FFMPEG error codes.  I tried to make sense of what I found and gave up, and set the script to basically not move forward on anything except a return of 0.  That way if it returns something else, the original file does not get deleted.

 

I'll look into your code and see if I can get it working.

Link to comment
Share on other sites

Cthalpa

Paste the following code into the file, and change the username and password to the appropriate values.  This is designed to be run on the actual Emby Server PC, but it could probably be modified to run on a different PC if needed.

 

I'd say, one would need to change the URL as well.. However, it would be a fairly easy feat, to grep the interface LAN or WAN protocol address (whether it be IPv4 or 6), to automatically set the parameter.

Link to comment
Share on other sites

muzicman0

I'd say, one would need to change the URL as well.. However, it would be a fairly easy feat, to grep the interface LAN or WAN protocol address (whether it be IPv4 or 6), to automatically set the parameter.

Not assuming it is being run on the same PC that Emby Server is on.  Unless I misunderstand what you mean.  127.0.0.1 is the localhost, so it will basically use the host PC.  I suppose if there are multiple NICs, then it may be an issue, then you would just change it to the IP address that Emby is bound to, which you can get from the Dashboard.  And of course, if you are using a non default port, then that should be changed as well.

Edited by muzicman0
Link to comment
Share on other sites

Cthalpa

Not assuming it is being run on the same PC that Emby Server is on.  Unless I misunderstand what you mean.  127.0.0.1 is the localhost, so it will basically use the host PC.  I suppose if there are multiple NICs, then it may be an issue, then you would just change it to the IP address that Emby is bound to, which you can get from the Dashboard.  And of course, if you are using a non default port, then that should be changed as well.

 

Exactly why I pointed out that your instructions should include to change the URL along with user/pass.

In my instance, I have a server thats full of harddrives, and a server thats full of CPU, RAM and GPU to run the actual streaming, so in my case, the IP would/could be different than the machine I actually run the script on (I would run the script on the server with GPU power, but the actual files are placed on a different server with a different IP).

 

In any case, you can grep your way out of anything. In a case where I would automate IP bound to emby and port, I would simply  do something like "ifconfig eth$ |grep ":emby":"string2" and parse it on something useable for the script (>$ip:port). Just giving my 2 cents for automation :)

  • Like 1
Link to comment
Share on other sites

muzicman0

Exactly why I pointed out that your instructions should include to change the URL along with user/pass.

In my instance, I have a server thats full of harddrives, and a server thats full of CPU, RAM and GPU to run the actual streaming, so in my case, the IP would/could be different than the machine I actually run the script on (I would run the script on the server with GPU power, but the actual files are placed on a different server with a different IP).

 

In any case, you can grep your way out of anything. In a case where I would automate IP bound to emby and port, I would simply  do something like "ifconfig eth$ |grep ":emby":"string2" and parse it on something useable for the script (>$ip:port). Just giving my 2 cents for automation :)

Thanks.  I'll add a note.  I'll look into getting the actual info to add to the script, and add it if I get it working well.  

 

EDIT: I changed it to read: "This is designed to be run on the actual Emby Server PC, but it could probably be modified to run on a different PC if needed.  If you are not running the script on the Emby Server, simply change the $embyServerURL variable to the correct IP address/port."

Edited by muzicman0
  • Like 2
Link to comment
Share on other sites

muzicman0

OK, now I am confused.  My Emby Server is the same version, but all of a sudden, the CSV format is different.  SeriesName used to be the 13th cell (starting from 0), but now it is 12.  I'm guessing others have changed as well.  Any ideas why this happened?

 

I guess I will parse the first line of the CSV and maybe set some variables for the index # of each relevant item.

Link to comment
Share on other sites

muzicman0

Not sure why the format changed, but I went ahead and made some changes to the script.  Now, as long as the column names in the CSV don't change, it should work fine.

Link to comment
Share on other sites

PenkethBoy

:)

 

expect things like that at anytime as Luke changes things all the time so from one beta to the next things change - work - dont work - can get frustrating - especially as very little if any warning is given

Link to comment
Share on other sites

muzicman0

I'm not using the Beta though, and as far as I can tell, the version didn't change.  Either way though, as long as the Column headers don't change, the new code should work fine.

Link to comment
Share on other sites

PenkethBoy

Ok - Then if you are only testing on Stable - you need to add that to your notes - so user are aware

 

Because lots of things can change in the api from one Stable to the next - and if you dont test in beta you wont be aware of them until the new Stable comes out

Link to comment
Share on other sites

muzicman0

That's a bit disturbing.  I can understand adding features, and I can understand fixing bugs (that may change functionality), but having wholesale changes from version to version is not a good thing. 

Link to comment
Share on other sites

Happy2Play

That's a bit disturbing.  I can understand adding features, and I can understand fixing bugs (that may change functionality), but having wholesale changes from version to version is not a good thing. 

now you know how all the custom css user feel. :)

 

That is also why almost ever plugin needs to be updated with every stable release. I know almost every plugin has already been updated in 4.4.x.x (at least all core plugins).

  • Like 1
Link to comment
Share on other sites

PenkethBoy

That's a bit disturbing.  I can understand adding features, and I can understand fixing bugs (that may change functionality), but having wholesale changes from version to version is not a good thing. 

i warned you because - supporting scripts/plugins can be a royal PIA - as things change and you then play catchup - it varies obviously but at its worst its like whack-a-mole

 

i have loads of emby scripts that i use to do stuff automatically - or work arounds to emby limitations - i dont usually publish them as i dont have the time to support them all unfortunately.

 

It's great you have posted your scripts - i'm sure they will get some good testing and requests to add this feature or that over time

 

Good luck and maybe you will be lucky with api changes :)

Link to comment
Share on other sites

  • 4 weeks later...
muzicman0

Just in case it hasn't been seen by those watching the thread, I am updating the original post with any new updates.  current changes are listed below:

 

Versions:

v1.5.0 - 03-14-2020

   -Rename the log file with a time stamp once it becomes over 1000 lines.

v1.4.0 - 03-10-2020

   -If the CSV file 'Date Modified' property doesn't match the current date, then the script will exit since there is likely no new information to process.

v1.3.0 - 03-02-2020

   -If the file is marked as watched, and is in the AutoCompressList.txt file, but is NOT a .ts file, it will be moved, but not compressed.

v1.2.0 - 02-22-2020

   -CSV output changed again for an unknown reason.  I am now parsing the season and episode from the path of the file.

   -Added a bit more logging

   -Fixed a bug where a ":" should have been changed in the filename to a "_" but was instead changed to a " ".

   -Removed characters on the String Replace function that would not cause issues.

   -Added a sort order to the powershell script to hopefully get all info each time

v1.1.1 - 02-19-2020

   -Fixed bug introduced in last revision where original file would not be deleted

v1.1.0 - 02-19-2020

   -It appears that the output columns in the CSV can change order, or content, so I implemented a change that would map the correct column to the variables

v1.0.0 - 02-17-2020

   -Initial release

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...