|
SageTV v7 Customizations This forums is for discussing and sharing user-created modifications for the SageTV version 7 application created by using the SageTV Studio or through the use of external plugins. Use this forum to discuss plugins for SageTV version 7 and newer. |
|
Thread Tools | Search this Thread | Display Modes |
#1
|
|||
|
|||
What Are you doing with SJQv4?
The main SJQv4 thread is a great resource for getting SJQv4 up and running, and for technical support, but how about this thread for sharing some ideas and code regarding the cool or interesting things you are doing with SJQv4?
__________________
HP m9040n Quad Core 2.4Ghz, Windows7 Ultimate, Ceton 4 tuner CableCard with SageDCT, 2 HDHomeRun QAM, Netgear 24 Port GiGE Switch, Linksys WRT600N Router, 3 HD200 Extenders, 2 SageTV Clients Server: SageTV 7 |
#2
|
|||
|
|||
Comskipping - both H.264 (HD-PVR) files and MPEG -2 files.
Kicking off SageTV Transcoding jobs and saving the transcoded file to a new folder based on the Show Title - ie. Dora the Explorer gets saved to \\server\Kids' Shows\Dora the Explorer\Showtitle.mp4
__________________
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 |
#3
|
|||
|
|||
A little taste of what I do...
Here's my SJQv4 crontab file: Code:
0 12 * * * SINGLEFAV 45 6,23 * * * SRETEST 45 4 * * * IMPORTSCAN 20 10-23/2 * * * RMARTIFACTS 53 11,18 * * * BLACKOUTMGR 50 11 * * * BACKUP 5 3 * * Sun FULLBACKUP 15 5 1 * * HDDIMG */30 2-9 * * * FINDARCHIVES
Also, I have my comskip task attached to all my favourites that need it (i.e. all of them except those from HBO, Movie channels, etc.). I comskip on the RecordingCompleted event. Most of the scripts talked about here are in my SageScripts svn repository.
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... |
#4
|
||||
|
||||
That's way cool Slugger! I have to admit I haven't followed SJQ at all... Honestly, I didn't realize all what was available either. I guess I'll have to give it a shot. It looks like you already have some scripts that I can use right out of the box.
|
#5
|
|||
|
|||
Now that is some cool stuff! Dumb question: Where is the SageScripts svn repository? Sorry, I should probably know.
__________________
HP m9040n Quad Core 2.4Ghz, Windows7 Ultimate, Ceton 4 tuner CableCard with SageDCT, 2 HDHomeRun QAM, Netgear 24 Port GiGE Switch, Linksys WRT600N Router, 3 HD200 Extenders, 2 SageTV Clients Server: SageTV 7 |
#6
|
|||
|
|||
I have tweaked the Comskip scripts to:
1. Run Showanalyzer .97 for MPG files from HDHomerun. 2. Run Showanalyzer 1.0x for TS files from Ceton (SageDCT). 3. Only run comskip processing when no recordings are happening, and none are scheduled for the next 30 minutes. Looking for more cool stuff to do.
__________________
HP m9040n Quad Core 2.4Ghz, Windows7 Ultimate, Ceton 4 tuner CableCard with SageDCT, 2 HDHomeRun QAM, Netgear 24 Port GiGE Switch, Linksys WRT600N Router, 3 HD200 Extenders, 2 SageTV Clients Server: SageTV 7 |
#7
|
|||
|
|||
SJQ is very cool! It takes some commitment to make it dance, but man can it dance!
__________________
HP m9040n Quad Core 2.4Ghz, Windows7 Ultimate, Ceton 4 tuner CableCard with SageDCT, 2 HDHomeRun QAM, Netgear 24 Port GiGE Switch, Linksys WRT600N Router, 3 HD200 Extenders, 2 SageTV Clients Server: SageTV 7 |
#8
|
|||
|
|||
Quote:
These are the tasks from my crontab, with the time fields removed and links to the exe script and, if necessary, the pretest script provided. Code:
SINGLEFAV | exe SRETEST | private scripts, used for internal SRE testing only BTFAVS | private scripts; lots of cleanup needed before I share IMPORTSCAN | private; literally one liner that calls media scan; pretest is a basic script that checks that there's nothing connected and no recordings scheduled for immediate future RMARTIFACTS | exe BLACKOUTMGR | private; needs major cleanup BACKUP | private; needs cleanup FULLBACKUP | pretest | exe HDDIMG | private; same as FULLBACKUP scripts (basically) except it calls my disk imaging tool to create a disk image instead of backing up SageTV app dir FINDARCHIVES | pretest | exe Quote:
EDIT: Ignore the tools dir in the repository. Everything under there is in the gtools.jar file that can be downloaded from the project site (or from the Sage plugin manager). The only thing you need to look at in the tools dir are the javadocs under the docs subdir to find out what tools are in there (they're all supplements/helpers/additons to the Sage API that can be used from Groovy and/or Java using the gtools.jar).
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... Last edited by Slugger; 06-06-2011 at 09:30 PM. |
#9
|
|||
|
|||
Great stuff Slugger. I am going to borrow a bunch of those and play!
__________________
HP m9040n Quad Core 2.4Ghz, Windows7 Ultimate, Ceton 4 tuner CableCard with SageDCT, 2 HDHomeRun QAM, Netgear 24 Port GiGE Switch, Linksys WRT600N Router, 3 HD200 Extenders, 2 SageTV Clients Server: SageTV 7 |
#10
|
||||
|
||||
Just starting to play with SJQ4 on my test machine. Need to learn the ropes (SJQ4 & SageTV V7) before putting into Production. Don't want to mess something up then have WAF plummet.
Plan is to play with the mv_media scripts test/exe to have it move the media (hopefully to show/season folder structure) to my nas, library scan, get new media info to unarchive it and other processing based upon different criteria. And parameterize as much as possible to make it generic. Comskip will be one of them also during certain time windows only and usage. I like the idea of the weekly backup. Question though is I notice when SageTV is stopped, the extenders turn themselves off and have to be turned back on to auto-connect. Not sure how that'll go for the WAF factor. fun fun fun...now just to find the time to play. |
#11
|
||||
|
||||
A little searching and found the solution for turning the extenders back on after shutting down/starting up SageTV service. http://forums.sagetv.com/forums/showthread.php?t=35464
Tested it out on my HD200 & HD300 and it works well. |
#12
|
|||
|
|||
@Slugger - Why do you need to run the import scan? Doesn't Sage run this on its own every few hours? And why worry if the server is doing other stuff while a media scan is taking place? I run import scans all the time when I am futzing around with correcting metadata and it never seems to cause issues.
__________________
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 |
#13
|
|||
|
|||
Quote:
Quote:
__________________
Twitter: @ddb_db Server: Intel i5-4570 Quad Core, 16GB RAM, 1 x 128GB OS SSD (Win7 Pro x64 SP1), 1 x 2TB media drive Capture: 2 x Colossus STB Controller: 1 x USB-UIRT Software:Java 1.7.0_71; SageTV 7.1.9 Clients: 1 x HD300, 2 x HD200, 1 x SageClient, 1 x PlaceShifter Plugins: Too many to list now... |
#14
|
||||
|
||||
Quote:
http://code.google.com/p/sagetv-addo...wner%20Summary |
#15
|
||||
|
||||
I'm doing a few things with sjq, with Sluggers help mostly....
1 - rename files to my archive format; for tv shows: series - SxxEyy for movies: title (year) 2 - comskip selectively 3 - edit the recording with videoredo to eliminate commercials. 3 - run handbrake to compress and remux to mkv selectively and drop in a different folder for archiving. All while maintaining the recording's metadata. certainly willing to post the code(s) if anyone's interested. |
#16
|
|||
|
|||
Quote:
__________________
HP m9040n Quad Core 2.4Ghz, Windows7 Ultimate, Ceton 4 tuner CableCard with SageDCT, 2 HDHomeRun QAM, Netgear 24 Port GiGE Switch, Linksys WRT600N Router, 3 HD200 Extenders, 2 SageTV Clients Server: SageTV 7 |
#17
|
||||
|
||||
VideoReDo scripts
Disclaimer - I'm not a programmer, I have no idea what I'm doing, and don't even fake it well. With that said, use at your own risk, let me know if something is unclear or you think of a better way to do any of this, I'd like to hear it. Some of this was pulled straight from Slugger's scripts, so some might look familiar Big thanks to him for his generous help!
Here's the VideoReDo test and exec scripts. What happens is the media_file_scanner.groovy script runs every so often via the sjq cron interface. I use 15 minutes, but can be whatever you like. You'll need to edit your comskip.ini to include the videoredo output.... The way this process works: Comskip runs seperately and outputs an .edl and .VPrj files. I review the VPrj manually in videoredo just to make sure comskip wasn't way off base (happens on a couple channels). I edit as necessary and save the project. Then add a '1' to the end of the .edl as a marker that sjq can test against. i.e: If an .edl1 file exists, do the script. I like for it to wait for me to review, if you want to skip that just edit the scanner script to look for .VPrj files rather than .edl1, comskip creates the .VPrj at the end of it's processing so should be safe to use. media_file_scanner.groovy- Code:
def testMode = false // If true, only print out which media files would be queued up, don't actually add the tasks to the queue def mediaMask = "T" // What types of media should be scanned? (T = TV, M = Music, V = Imported Video, D = DVD, B = BluRay, P = Pictures; TMV = TV + Music + Imports, etc.) def taskIds = ["CUT"] // ,"HANDBRAKE" Multiple tasks can be listed, separated by commas def needsProcessing(Object mediaFile) { if(hasArtifacts(mediaFile, ["edl1"])) // This function is defined at the bottom of the file return true // All our tests have passed so return false return false } import com.google.code.sagetvaddons.sjq.network.ServerClient import com.google.code.sagetvaddons.metadata.Factory import org.apache.commons.io.FilenameUtils import org.apache.commons.io.FileUtils def sc = !testMode ? new ServerClient() : null MediaFileAPI.GetMediaFiles("T").each { mediaFile -> if (MediaFileAPI.IsTVFile(mediaFile)){ if (needsProcessing(mediaFile)) { if (!testMode) { taskIds.each { id -> sc.addTask(id, Factory.getMap(mediaFile)) println "Will queue up '${MediaFileAPI.GetMediaTitle(mediaFile)}' (${MediaFileAPI.GetMediaFileID(mediaFile)})" } } else println "Would queue up '${MediaFileAPI.GetMediaTitle(mediaFile)}' (${MediaFileAPI.GetMediaFileID(mediaFile)}); skipped because test mode is TRUE" } } } if(sc != null) sc.close() return 0 // Returns true if any segment of the given media file has at least one artifact of any of the given artifact extensions; false otherwise def hasArtifacts(Object mediaFile, List exts) { for(def it : MediaFileAPI.GetSegmentFiles(mediaFile)) { def absPath = it.getAbsolutePath() def dir = FilenameUtils.getFullPath(absPath) def base = FilenameUtils.getBaseName(absPath) for(def ext : exts) { def artifact = "${dir}${base}.$ext" def artifactRename = "${dir}${base}.edl2" if(Utility.IsFilePath(artifact)){ FileUtils.moveFile(new File(artifact), new File(artifactRename)) return true } } } return false } Code:
import sagex.UIContext def mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) // def mf = MediaFileAPI.GetMediaFileForID(4548538) // For testing use this line, edit the ID and comment out the prior line.... // If it's still recording, then our script is foobar, but we'll go to the bottom of the queue and wait.... if(MediaFileAPI.IsFileCurrentlyRecording(mf)) { println("Recording in progress, waiting..."); return 1; } // Let's make sure nothing is locking this recording, if they are it bombs. def connected = [] connected += Arrays.asList(Global.GetUIContextNames()) connected += Arrays.asList(Global.GetConnectedClients()) println "Connected: $connected" def active = [] for(def c : connected) { def nowPlaying = MediaPlayerAPI.GetCurrentMediaFile(new UIContext(c)) if(nowPlaying != null) { active.add(nowPlaying) println "Client '$c' is playing '${MediaFileAPI.GetMediaTitle(nowPlaying)}/${MediaFileAPI.GetMediaFileID(nowPlaying)}'" } } println "Checking if someone is playing the media file in question (def mf)..." for(def playing : active) { if(MediaFileAPI.GetMediaFileID(mf) == MediaFileAPI.GetMediaFileID(playing)) { println "Someone's playing this media file!" return 1 } } println "File is clear and ready!" return 0 Code:
// def SJQ4_METADATA = ["SJQ4_ID":"4704439", "SJQ4_TYPE":"MediaFile"] // Edit this line if testing on a specific recording. // comment or remove the above line before using the scirpt in SJQv4. import org.apache.commons.io.FilenameUtils import org.apache.commons.io.FileUtils import com.google.code.sagetvaddons.sjq.network.ServerClient import com.google.code.sagetvaddons.metadata.Factory private class Settings { static public final boolean TEST_MODE = false } def mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) if(mf == null) { //make sure it's a valid file id println "Invalid media file id! [${SJQ4_METADATA['SJQ4_ID']}]" return 1 } // Elements Definition def Origdir = ((MediaFileAPI.GetParentDirectory(mf).toString()) + "\\") def CutDir = "\\\\Sage-pc\\Mirror_Set\\Process_TV\\com_free\\" def Prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath()) def CutExt = ".ts" // construction zone def FullInputFile = new File(Origdir + Prefix + CutExt) def FullCutFile = new File(CutDir + Prefix + CutExt) def VRDSourceFile = new File(Origdir + Prefix + ".VPrj") // Let's make sure output is unique def i = 1 def file = new File(FullCutFile.toString()) while(file.exists()) file = new File(CutDir, "$Prefix-${i++}$CutExt") println "New file will be: $file" FullCutFile = file println VRDSourceFile println FullCutFile println FullInputFile // Run VideoReDo println "Cutting files From this project '${VRDSourceFile}' to '${FullCutFile}'." def command = ('cscript.exe //nologo "C:\\Program Files (x86)\\VideoReDoTVSuite4\\vp.vbs " "' + VRDSourceFile + '" "' + FullCutFile + '" "/p:H.264 Transport Stream" /q /e') println "full cut command will be '$command'" if(!Settings.TEST_MODE) { // Are we running test mode, if not do this def proc = command.execute() def initialSize = 4096 def outStream = new ByteArrayOutputStream(initialSize) def errStream = new ByteArrayOutputStream(initialSize) proc.consumeProcessOutput(outStream, errStream) proc.waitFor() println 'out:\n' + outStream println 'err:\n' + errStream } else { // if we are in test mode do this println "Would run '$command' if test mode were disabled!" } // link ExternalID to FullCutFile if(!Settings.TEST_MODE) { // Are we running test mode, if not do this // the three minute rule applies so reinit this variable mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) def src = (FullCutFile.toString()) println "fullpathfile is=$src" def sid = ShowAPI.GetShowExternalID(mf) println "ExternalID is ${sid}" if(!Utility.IsFilePath(src)) { println "${src} does not exist!" return 1 } if(MediaFileAPI.GetMediaFileForFilePath(new File(src)) != null) { println "${src} is already a registered SageTV media file!" return 1 } def show = ShowAPI.GetShowForExternalID(sid) if(show == null) { println "ShowEID ${sid} is invalid!" return 1 } def mfadd = MediaFileAPI.AddMediaFile(new File(src), null) if(mfadd == null) { println "Failed to add media file!" return 1 } if(!MediaFileAPI.SetMediaFileShow(mfadd, show)) { println "Failed to link show metadata to media file!" return 1 } MediaFileAPI.MoveTVFileOutOfLibrary(mfadd) println "Imported '${src}' and linked it to ShowEID '${sid}'!" // Get object info from new file and pass it to HANDBRAKE def mf2 = MediaFileAPI.GetMediaFileForFilePath(FullCutFile) def NewSourceFile = MediaFileAPI.GetFileForSegment(mf2, 0) def sc = new ServerClient() def taskId = 'HANDBRAKE' def metadata = Factory.getMap(mf2) sc.addTask(taskId, metadata) sc.close() } else { // if we are in test mode do this println "Would have relinked the showID '${sid}' to the new file '${src}' if test mode were disabled!" } // Let's delete the original files since that was successful if(!Settings.TEST_MODE) { // Are we running test mode, if not do this MediaFileAPI.DeleteFile(mf) Utility.DirectoryListing(new File(Origdir)).each { if(FilenameUtils.wildcardMatchOnSystem(it.getName(), "${Prefix}.*")) { def fileName = new File(Origdir, Prefix + (it.getName().substring(it.getName().indexOf('.')))) try { fileName.delete() } catch(IOException e) { e.printStackTrace() } } } } else { // if we are in test mode do this println "Would delete ${Prefix}.* if test mode were disabled!" } return 0 |
#18
|
||||
|
||||
Handbrake scripts
And here are the handbrake scripts.
The hand_brake_test.groovy essentially just makes sure the file isn't locked. Code:
import sagex.UIContext def mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) // def mf = MediaFileAPI.GetMediaFileForID(4704415) // This is what we're testing against, fill it in someway, some how // If it's still recording, then our script is foobar, but we'll wait go to the bottom of the queue and wait.... if(MediaFileAPI.IsFileCurrentlyRecording(mf)) { println("Recording in progress, waiting..."); return 1; } def connected = [] connected += Arrays.asList(Global.GetUIContextNames()) connected += Arrays.asList(Global.GetConnectedClients()) println "Connected: $connected" def active = [] for(def c : connected) { def nowPlaying = MediaPlayerAPI.GetCurrentMediaFile(new UIContext(c)) if(nowPlaying != null) { active.add(nowPlaying) println "Client '$c' is playing '${MediaFileAPI.GetMediaTitle(nowPlaying)}/${MediaFileAPI.GetMediaFileID(nowPlaying)}'" } } println "Checking if someone is playing the media file in question (def mf)..." for(def playing : active) { if(MediaFileAPI.GetMediaFileID(mf) == MediaFileAPI.GetMediaFileID(playing)) { println "Someone's playing this media file!" return 1 } } println "File is clear and ready!" return 0 Code:
// def SJQ4_METADATA = ["SJQ4_ID":"4704442", "SJQ4_TYPE":"MediaFile"] // remove the above line before using the scirpt in SJQv4. import org.apache.commons.io.FilenameUtils import org.apache.commons.io.FileUtils private class Settings { static public final boolean TEST_MODE = false } def mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) if(mf == null) { //make sure it's a valid file id println "Invalid media file id! [${SJQ4_METADATA['SJQ4_ID']}]" return 1 } // Elements Definition def CutDir = ((MediaFileAPI.GetParentDirectory(mf).toString()) + "\\") def HBDir = "D:\\Process_TV\\com_free\\handbrake\\" def Prefix = FilenameUtils.getBaseName(MediaFileAPI.GetFileForSegment(mf, 0).getAbsolutePath()) def SourceFile = MediaFileAPI.GetFileForSegment(mf, 0) // Construction zone def CutFile = new File(Prefix + ".ts") def HBFile = new File(Prefix + ".mkv") def FullCutFile = "D:\\Process_TV\\com_free\\" + CutFile def FullHBFile = HBDir + HBFile // Don't compress these, just move them to final location if(MediaFileAPI.GetMediaTitle(mf) =~ /News|MLB Baseball|NHL Hockey|College Basketball|Racing|racing|AMA|race/){ println "We got Racing!" FullCutFile2 = new File(FullCutFile) try { FileUtils.moveFile(SourceFile, new File(HBDir + CutFile)) } catch(IOException e) { e.printStackTrace() } return 0 } // Shrink-i-dink with HandBrake def i = 1 def file = new File(FullHBFile) while(file.exists()) file = new File(HBDir, "$Prefix-${i++}.ts") FullHBFile = file def command = """C:\\Program Files (x86)\\Handbrake\\HandBrakeCLI.exe""" + """ -i "${FullCutFile}" -o "${FullHBFile}" -f mkv -q 0.86 -x ref=3:mixed-refs=2:bframes=3:b-pyramid=1:b-rdo=1:bime=1:weightb=1:subme=6:trellis=1:analyse=all:8x8dct=1:vbv-maxrate=25000 -5 -E ac3 -6 none""" println "full command will be '$command'" if(!Settings.TEST_MODE) { // Are we running test mode, if not do this def proc = command.execute() def initialSize = 4096 def outStream = new ByteArrayOutputStream(initialSize) def errStream = new ByteArrayOutputStream(initialSize) proc.consumeProcessOutput(outStream, errStream) proc.waitFor() println 'out:\n' + outStream println 'err:\n' + errStream //relink ExternalID to new file // the three minute rule applies, so reinit this variable. mf = MediaFileAPI.GetMediaFileForID(SJQ4_METADATA["SJQ4_ID"].toInteger()) def src = (FullHBFile.toString()) println "fullpathfile is=$src" def sid = ShowAPI.GetShowExternalID(mf) println "ExternalID is ${sid}" if(!Utility.IsFilePath(src)) { println "${src} does not exist!" return 1 } if(MediaFileAPI.GetMediaFileForFilePath(new File(src)) != null) { println "${src} is already a registered SageTV media file!" return 1 } def show = ShowAPI.GetShowForExternalID(sid) if(show == null) { println "ShowEID ${sid} is invalid!" return 1 } def mfadd = MediaFileAPI.AddMediaFile(new File(src), null) if(mfadd == null) { println "Failed to add media file!" return 1 } if(!MediaFileAPI.SetMediaFileShow(mfadd, show)) { println "Failed to link show metadata to media file!" return 1 } MediaFileAPI.MoveTVFileOutOfLibrary(mfadd) println "Imported '${src}' and linked it to ShowEID '${sid}'!" // Delete the CUT file MediaFileAPI.DeleteFile(mf) // Delete any flac associated with the CUT file Utility.DirectoryListing(new File(CutDir)).each { if(FilenameUtils.wildcardMatchOnSystem(it.getName(), "${Prefix}.*")) { def fileName = new File(CutDir, Prefix + (it.getName().substring(it.getName().indexOf('.')))) try { fileName.delete() } catch(IOException e) { e.printStackTrace() } } } return 0 } else { // if we are in test mode do this println "Would run '$command' if test mode were disabled!" } |
#19
|
|||
|
|||
__________________
HP m9040n Quad Core 2.4Ghz, Windows7 Ultimate, Ceton 4 tuner CableCard with SageDCT, 2 HDHomeRun QAM, Netgear 24 Port GiGE Switch, Linksys WRT600N Router, 3 HD200 Extenders, 2 SageTV Clients Server: SageTV 7 |
#20
|
||||
|
||||
Quote:
Are you moving the recordings to a more XBMC friendly format (Series Name>Season #>Episode.mpg) format and still keeping the link to SageTV's internal Db to keep the watched status accurate ala the link media script? I ask in that this may be a MUCH simpler method for me to use for sharing the files for use within XBMC. I have tried a number of other methods (symlinking, .strm files, etc...) and for one reason or another, they never work across all the variants of XBMC (PC/ATV/Mac). If I could simply move the recorded TV files to a different directory structure, keep the associated edl/properties files and ensure that the internal SageTV Database is kept accurate/linked (keeping the watched/dont like/etc status), I could then simply point XBMC to the newly formed SageTV recodings folder(s) and move on! If you tell me that is what you have, then please, post the code! -Jason
__________________
True standalone tuner functionality with the --> HAVA Channel Changer<-- |
Tags |
sjq, sjqv4 |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Plugin: SJQv4 | Slugger | SageTV v7 Customizations | 1639 | 02-19-2022 03:04 PM |
Need help with SJQv4 remote agent | coppit | SageTV v7 Customizations | 4 | 12-19-2010 11:03 AM |
SJQv4: Technology Preview | Slugger | SageTV v7 Customizations | 39 | 12-17-2010 01:17 PM |
SJQv4: Design Discussion | Slugger | SageTV v7 Customizations | 26 | 10-18-2010 08:22 AM |