|
SageTV Software Discussion related to the SageTV application produced by SageTV. Questions, issues, problems, suggestions, etc. relating to the SageTV software application should be posted here. (Check the descriptions of the other forums; all hardware related questions go in the Hardware Support forum, etc. And, post in the customizations forum instead if any customizations are active.) |
|
Thread Tools | Search this Thread | Display Modes |
#1
|
|||
|
|||
Recording (Favorite) to Specific Directory
I know long ago this was not possible; has anything changed in the last 6-8 years that would now allow for a Recording (Favorite) to be recorded to a Specific Directory?
|
#2
|
|||
|
|||
No
__________________
Channels DVR UBUNTU Server 2 Primes 3 Connects TVE SageTV Docker with input from Channels DVR XMLTV and M3U VIA Opendct. |
#3
|
|||
|
|||
The option is certainly available through the web UI
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server |
#4
|
||||
|
||||
Please elaborate
|
#5
|
|||
|
|||
This assumes that you have the SageTV Jetty webserver installed.
Then go to Schedule Recordings - Favorites Manager and click on one of your favorites. You should see an option for Original Folder or Alternate Destination Folder which you can then enter.
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server |
#6
|
|||
|
|||
Does that work even if you are not converting to a different format (i.e. Automatic Conversion=No)?
__________________
Server: MSI Z270 SLI Plus ATX Motherboard, Intel i7-7700T CPU, 32GB Memory, Unraid 6.11.5, sagetvopen-sagetv-server-opendct-java11 Docker (version 2.0.7) Tuners: 2 x SiliconDust HDHomeRun Prime Cable TV Tuners, SiliconDust HDHomeRun CONNECT 4K OTA Tuner Clients: Multiple HD300 Extenders, Multiple Fire TV Stick 4K Max w/MiniClient Miscellaneous: Multiple Sony RM-VLZ620 Universal Remote Controls |
#7
|
|||
|
|||
I just checked, all the same options are available under the standard SageTV gui, the web ui is not necessary. Go to Favorites Manager, click on one of the favorites listed, and there is an Automatic Conversion option towards the bottom of the screen.
But I have a feeling that it only works for files that are automatically converted to a different format, not for the original file.
__________________
Server: MSI Z270 SLI Plus ATX Motherboard, Intel i7-7700T CPU, 32GB Memory, Unraid 6.11.5, sagetvopen-sagetv-server-opendct-java11 Docker (version 2.0.7) Tuners: 2 x SiliconDust HDHomeRun Prime Cable TV Tuners, SiliconDust HDHomeRun CONNECT 4K OTA Tuner Clients: Multiple HD300 Extenders, Multiple Fire TV Stick 4K Max w/MiniClient Miscellaneous: Multiple Sony RM-VLZ620 Universal Remote Controls |
#8
|
|||
|
|||
The other option is to use SJQ to run an external process. I used to have a process that would use handbrake to transcode shows to mp4 and move to a specific folder based on the Show Title.
__________________
New Server - Sage9 on unRAID 2xHD-PVR, HDHR for OTA Old Server - Sage7 on Win7Pro-i660CPU with 4.6TB, HD-PVR, HDHR OTA, HVR-1850 OTA Clients - 2xHD-300, 8xHD-200 Extenders, Client+2xPlaceshifter and a WHS which acts as a backup Sage server Last edited by wayner; 08-24-2020 at 07:06 AM. |
#9
|
||||
|
||||
I record to a local drive on the SageTV server to a single directory. Then nightly use SJQ to move them to my NAS in Show Title/Season ##/<filename.mpg>
|
#10
|
||||
|
||||
Can you share how that is done? This is exactly what I'd like to do. I am unfamiliar with SJQ
__________________
Intel Core i5-2500, 16GB RAM, OMV Linux 4.17, 3 TB of Data SageTV 9 Docker, Open DCT Docker Silicondust HDHomeRun Duo + Quatro Sage Mini Client on Amazon Fire Sticks and Android TVs |
#11
|
||||
|
||||
This is really handy and I wish I had known about. I have four external HDs and multi-episode recordings get spread all over the place. I have had to periodically manually move them to a common location... a real pain.
|
#12
|
|||
|
|||
Thanks for the feedback. Since it appears the embedded solution requires conversion, would if be possible to add a no conversion selection?
|
#13
|
||||
|
||||
Sure I’ll post the code i use tomorrow
|
#14
|
|||
|
|||
As a test I setup a favorite and selected the conversion type, quality and location. Video completed and nothing happened?
When does this process take place?? |
#15
|
||||
|
||||
For SJQ.
Attached screenshots of how I have the tasks set in SJQ Cron entry triggers the TV2Move script which looks for files to move to nas and triggers a movemedia task for each file to be moved I have had this in place for a long long time. Please review for what might need to be changed for your setup. Been ages since I looked at the code. I am a Windows setup for the Sage Server and NAS is unRaid. TV2MOVE: Code:
import com.google.code.sagetvaddons.sjq.network.ServerClient; import com.google.code.sagetvaddons.metadata.Factory; import com.google.code.sagetvaddons.groovy.api.MediaFileHelpers ; // What directory are we moving archives to? File dest = new File("\\\\tower\\"); // Queued tasks are marked with this metadata value String SJQ4_QUEUED = "SJQ4_ARCHIVED"; // Are we running on Windows? File names are not case sensitive on Windows so we need to handle that boolean isWindows = System.getProperty("os.name").contains("Windows"); ServerClient clnt = new ServerClient(); int i = 0; for(Object mediaFile : MediaFileAPI.GetMediaFiles("T")) { String filePath = MediaFileAPI.GetFileForSegment(mediaFile, 0).getAbsolutePath(); String ShowName = SJQ4_METADATA.get("SJQ4_SEGMENT_0"); if(isWindows) filePath = filePath.toLowerCase(); // If the media file is already stored on the NAS, it's already been queued or it's actively recording then just skip it if(filePath.startsWith(isWindows ? dest.toString().toLowerCase() : dest.toString()) || MediaFileAPI.IsFileCurrentlyRecording(mediaFile) || MediaFileHelpers.isBeingViewed(mediaFile)) continue; println (filePath + " to be moved ... ") ; clnt.addTask("MVMEDIALR", Factory.getMap(mediaFile)); MediaFileAPI.SetMediaFileMetadata(mediaFile, SJQ4_QUEUED, "1"); // } } clnt.close(); return 0; MoveMedia: Code:
/****************************************************************************** Move a SageTV Media File Last Modified: 16 Feb 2011 Author: Derek Battams <derek AT battams DOT ca> Use this groovy script to move a SageTV media file object from one location to another. The media file to be moved is defined by the SJQ4_ID environment variable; the SJQ4_TYPE variable must also be "MediaFile". The destination is given as the first command line argument to this script. The destination is a directory. This script will trigger a rescan of your media after a successful move; the rescan is necessary in order for SageTV to recognize the media file in its new location. ******************************************************************************/ boolean testMode = false; // Don't actually move any files, just print out what would be done String flagsFile="\\\\PWM1\\Users\\PWM\\Documents\\SageTV\\Move_Recordings_Output\\HTPC-LR\\Move_Recordings_Output.txt" ; /******************* DO NOT EDIT BELOW THIS LINE ************************/ // But if you do then send me your bug fix patches! ;) import org.apache.commons.io.FileUtils; import static groovy.io.FileType.*; import com.google.code.sagetvaddons.sjq.network.ServerClient; import java.io.*; import java.util.*; import java.text.SimpleDateFormat; import java.text.DateFormat; public WriteToFile(String outputFileName, String content) { try { File outputFile = new File(outputFileName); // if file doesnt exists, then create it if (!outputFile.exists()) { outputFile.createNewFile(); } // true = append to file FileWriter fw = new FileWriter(outputFile.getAbsoluteFile(),true); BufferedWriter bw = new BufferedWriter(fw); bw.write(content); // \n = new line feed bw.write("\n"); bw.close(); } catch (IOException e) { e.printStackTrace(); } } DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HHmm") ; Date runDate = new Date(); //string runDT = dateFormat.format(runDate) String ShowName = SJQ4_METADATA.get("SJQ4_SEGMENT_0"); String type = SJQ4_METADATA.get("SJQ4_TYPE"); String id = SJQ4_METADATA.get("SJQ4_ID"); File dest = new File("${SJQ4_ARGS[0]}"); String NewShow = "${SJQ4_ARGS[0]}/${ShowName}"; String SJQ4_QUEUED = "SJQ4_ARCHIVED"; String flagSettings ; println ("Parm passed = " + SJQ4_ARGS[0] ); println ("New File = ${NewShow}"); boolean RC ; if(!dest.isDirectory() && !dest.mkdirs()) { println("Destination directory is invalid! [" + dest.getAbsolutePath() + "]"); return 1; } if(!"MediaFile".equals(type) || id == null || !id.matches("\\d+")) { println("No media file attributes provided!"); return 1; } Object mediaFile = MediaFileAPI.GetMediaFileForID(id.toInteger()); if(mediaFile == null) { println("No media file for id " + id); return 1; } if(MediaFileAPI.GetNumberOfSegments(mediaFile) == 0) { println("Zero file segments for media file; nothing to move!"); return 1; } boolean WatchedFlag = AiringAPI.IsWatched(mediaFile) ; boolean ArchivedFlag = MediaFileAPI.IsLibraryFile(mediaFile) ; boolean LikeFlag = AiringAPI.IsDontLike(mediaFile) int origAiringID = AiringAPI.GetAiringID(mediaFile); String showExternalID = ShowAPI.GetShowExternalID(mediaFile); println("Moving " + Arrays.toString(MediaFileAPI.GetSegmentFiles(mediaFile)) + " to destination: " + dest.getAbsolutePath()); // Copy all segments then delete the originals if more than one segment otherwise just do a filesystem move op if(MediaFileAPI.GetNumberOfSegments(mediaFile) == 1) { try { if(!testMode) FileUtils.moveFileToDirectory(MediaFileAPI.GetFileForSegment(mediaFile, 0), dest, false); else println("Would move: " + MediaFileAPI.GetFileForSegment(mediaFile, 0)); } catch(IOException e) { println("Failed to move file to destination!"); e.printStackTrace(); return 1; } } else { def copied = []; // Copy the files to their new home for(File segment : MediaFileAPI.GetSegmentFiles(MediaFileAPI.GetMediaFileForID(id.toInteger()))) { try { if(!testMode) { FileUtils.copyFileToDirectory(segment, dest, true); copied.add(new File(dest, segment.getName())); println("\tCopy of '" + segment.getAbsolutePath() + "' completed..."); } else { println("\tWould move: " + segment.getAbsolutePath()); } } catch(IOException e) { println("Error copying segment '" + segment.getAbsolutePath() + "' to destination!"); e.printStackTrace(); copied.each { if(!it.delete()) println("Failed to delete '" + it.getAbsolutePath() + "'"); } return 1; } } } println("Moving artifacts..."); mvArtifacts(id.toInteger(), dest, testMode); if(!testMode) { RC=MediaFileAPI.DeleteFile(MediaFileAPI.GetMediaFileForID(id.toInteger())); if ( !RC ) { println ("DeleteFile failed"); } else { println ("DeleteFile success"); } File NewFile = new File(NewShow); println ("NewFile string = " + NewFile.toString() ); RC=MediaFileAPI.AddMediaFile(NewFile, null); if ( !RC ) { println ("AddMediaFile failed"); } else { println ("AddMediaFile success"); } Object mfNew = MediaFileAPI.GetMediaFileForFilePath(NewFile); if (mfNew == null ) { println ("mfNew is null") ; } Object origAiring = AiringAPI.GetAiringForID(origAiringID); RC=MediaFileAPI.SetMediaFileAiring(mfNew,origAiring ) ; if ( !RC ) { println ("SetMediaFileShow failed"); } else { println ("SetMediaFileShow success"); } if ( WatchedFlag ) { AiringAPI.SetWatched(mfNew); println("${NewShow} Should be Watched..."); isWatched = "Watched" ; } else { AiringAPI.ClearWatched(mfNew); println("${NewShow} Should be Unwatched..."); isWatched = "Unwatched" ; } if ( LikeFlag ) { AiringAPI.SetDontLike(mfNew); println("${NewShow} Should be Don't Like..."); dontLike = "Don't Like" ; } else { AiringAPI.ClearDontLike(mfNew); println("${NewShow} Should be Like..."); dontLike = "Like" ; } if ( ArchivedFlag ) { MediaFileAPI.MoveFileToLibrary(mfNew); println("${NewShow} Should be Archived..."); isArchived = "Archived" ; } else { MediaFileAPI.MoveTVFileOutOfLibrary(mfNew); println("${NewShow} Should be UnArchived..."); isArchived = "UnArchived" ; } AiringAPI.Record(MediaFileAPI.GetMediaFileAiring(mfNew)); flagSettings= dateFormat.format(runDate) + "|" + NewFile.toString() + "|${origAiringID}|${isArchived}|${isWatched}|${dontLike}" ; // println ("Just BEFORE WriteToFile" ) ; // println (flagSettings) ; WriteToFile(flagsFile, flagSettings) ; } //MediaFileAPI.SetMediaFileMetadata(mediaFile, SJQ4_QUEUED, "1"); println ("Move completed") ; return 0; def mvArtifacts(int mfId, File dest, boolean testMode) { for(File segment : MediaFileAPI.GetSegmentFiles(MediaFileAPI.GetMediaFileForID(mfId))) { String prefix = segment.getName().substring(0, segment.getName().lastIndexOf('.')); File baseDir = new File(segment.getParent()); baseDir.eachFileMatch FILES, {!new File(baseDir, it.toString()).equals(segment) && it.toString().startsWith(prefix)}, { File artifact = new File(baseDir, it.getName()); if(!testMode) { FileUtils.moveFileToDirectory artifact, dest, false; } else println("Would move artifact: " + artifact.getAbsolutePath()); } } } Last edited by graywolf; 08-25-2020 at 07:41 AM. |
#16
|
|||
|
|||
Quote:
Nothing in the sagetv_0.txt file that I can find (assuming this is the log file) |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Automatically move specific favorite after each recording finishes | TwistedMelon | SageTV v9 Customizations | 17 | 01-02-2018 08:04 PM |
How to exclude s specific import directory from a view ? | hoep | Batch Metadata Tools | 3 | 05-18-2011 08:20 AM |
New Feature: Define Archive to specific directory | jominor | SageTV Software | 10 | 02-21-2007 07:10 PM |
Is it possible to move a file to a specific directory | ldavis | SageTV Software | 0 | 09-20-2003 08:45 AM |
Prevent recording a favorite on a specific channel | BLS | SageTV Software | 4 | 08-29-2003 01:05 PM |