SageTV Community  

Go Back   SageTV Community > SageTV Products > SageTV Software

Notices

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.)

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 02-02-2022, 02:39 PM
graywolf's Avatar
graywolf graywolf is offline
Sage Icon
 
Join Date: Oct 2009
Location: NC
Posts: 1,370
Multiple Tuners question - which was used?

If you have multiple tuners, how do you know which tuner was used to record a show?

i.e you have 2 hvr-1600s (yea...still old school SD), how do you know which one recorded which show?
Reply With Quote
  #2  
Old 02-02-2022, 02:44 PM
KeithAbbott KeithAbbott is offline
Sage Icon
 
Join Date: Oct 2009
Location: Southeastern Michigan
Posts: 1,355
Go to "View Recording Detail" for the show, and scroll all the way down. The tuner will be listed under the "Encoded by:" section.
__________________
Server: MSI Z270 SLI Plus ATX Motherboard, Intel i7-7700T CPU, 32GB Memory, Unraid 6.10.3, sagetvopen-sagetv-server-opendct-java11 Docker (version 2.0.6)
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
Reply With Quote
  #3  
Old 02-02-2022, 03:10 PM
graywolf's Avatar
graywolf graywolf is offline
Sage Icon
 
Join Date: Oct 2009
Location: NC
Posts: 1,370
Hmmm. Don't see an Encoded By section currently.
Maybe because I currently only have 1 tuner?
Or is it a config somewhere to have it display?
Reply With Quote
  #4  
Old 02-02-2022, 03:17 PM
KeithAbbott KeithAbbott is offline
Sage Icon
 
Join Date: Oct 2009
Location: Southeastern Michigan
Posts: 1,355
Here's a screen capture/example:



I use OpenDCT, so maybe it's possible that it displays differently than native SageTV. But I would still think that SageTV would have some equivalent. Does it display the tuner for a show that you are watching live?
Attached Images
File Type: jpg Encoded by Example.jpg (98.9 KB, 172 views)
__________________
Server: MSI Z270 SLI Plus ATX Motherboard, Intel i7-7700T CPU, 32GB Memory, Unraid 6.10.3, sagetvopen-sagetv-server-opendct-java11 Docker (version 2.0.6)
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
Reply With Quote
  #5  
Old 02-02-2022, 07:47 PM
wnjj wnjj is offline
Sage Icon
 
Join Date: Jan 2009
Posts: 1,484
I use stock SageTV and it shows the encoded by on all recordings, even ones for which no longer have the tuner.
__________________
Windows Installer
Reply With Quote
  #6  
Old 02-02-2022, 08:04 PM
wayner wayner is offline
SageTVaholic
 
Join Date: Jan 2008
Location: Toronto, ON
Posts: 7,413
Or look at the show in the web client:

Code:
FIFA World Cup 2022 Qualifying

Episode: El Salvador vs. Canada

Manual RecordingFirst RunHDTV markerMonitor status unknown.

Airing: Feb 2, 2022 8:30 PM - 11:30 PM

Duration: 3h 0m

Channel: 502-SN1HD

Description: 3rd Round.

Category: Sports event / Soccer

Closed Captioned, HDTV

Show ID: EP033149890526

SRE Status: Monitor status unknown. <Edit | Delete>

Encoded by: Hauppauge HD PVR 00A20BC4 Great-H.264

File Format: MPEG2-TS[H.264 16:9 1080i@29.97fps, AAC@48kHz Stereo]

Files:
/var/media/tv/FIFAWorldCup2022Qualifying-ElSalvadorvsCanada-437926-0.ts

File Playlists: [wvx] [m3u] [pls]

Size: 2.03GB

Internal details: MediaFileID=1133147 , AiringID=437926

[Edit Show Info]

[Import XML Show Info]
__________________
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
Reply With Quote
  #7  
Old 02-03-2022, 06:43 AM
graywolf's Avatar
graywolf graywolf is offline
Sage Icon
 
Join Date: Oct 2009
Location: NC
Posts: 1,370
OK. something I need to figure out.
Appears that I do see the Encoded by: on recordings when they still reside on the local hard drive but nightly I have them moved to the NAS. I'll have to review my process because it appears that when I move from local SageTV PC Drive to NAS the MediaFileID changes (AiringID stays same) and that looks like when I lose the Encoded by: information
Reply With Quote
  #8  
Old 02-04-2022, 12:00 PM
graywolf's Avatar
graywolf graywolf is offline
Sage Icon
 
Join Date: Oct 2009
Location: NC
Posts: 1,370
Is there an API call where you can set the Encoded By: value to a MediaFile/AiringID?

Trying to think of how best to redo how I move recordings from local PC hard drive to NAS and still retain the Encoded By value.

Or if anyone is out there that moves Recordings from local disk to NAS that retains the flags (archived, watched, dont like) and the Encoded by, I would be interested in seeing how their script is doing it.
Reply With Quote
  #9  
Old 02-04-2022, 04:00 PM
wnjj wnjj is offline
Sage Icon
 
Join Date: Jan 2009
Posts: 1,484
Quote:
Originally Posted by graywolf View Post
OK. something I need to figure out.
Appears that I do see the Encoded by: on recordings when they still reside on the local hard drive but nightly I have them moved to the NAS. I'll have to review my process because it appears that when I move from local SageTV PC Drive to NAS the MediaFileID changes (AiringID stays same) and that looks like when I lose the Encoded by: information
Yep. It looks like those are considered “recovered files” and the meta data is read from the file. Since the path changed it’s a new object in the database. See here in the code where “encodedBy” is set to nothing for recovered files: https://github.com/google/sagetv/blo...ard.java#L3583
__________________
Windows Installer
Reply With Quote
  #10  
Old 02-04-2022, 10:36 PM
jpwegas jpwegas is offline
Sage Expert
 
Join Date: May 2007
Posts: 500
Quote:
Originally Posted by wnjj View Post
Yep. It looks like those are considered “recovered files” and the meta data is read from the file. Since the path changed it’s a new object in the database. See here in the code where “encodedBy” is set to nothing for recovered files: https://github.com/google/sagetv/blo...ard.java#L3583
Interesting. I wonder what triggers it thinking it's a recovered file. It can't be just the path change alone that triggers this. When I move my recordings to a new (locally attached) drive I use a new path and most (but not all) of the files keep their "encodedBy" data. Wondering if it's a local vs. NAS issue or Linux vs. Windows (I'm on Linux).

--John
Reply With Quote
  #11  
Old 02-04-2022, 11:46 PM
wnjj wnjj is offline
Sage Icon
 
Join Date: Jan 2009
Posts: 1,484
Quote:
Originally Posted by jpwegas View Post
Interesting. I wonder what triggers it thinking it's a recovered file. It can't be just the path change alone that triggers this. When I move my recordings to a new (locally attached) drive I use a new path and most (but not all) of the files keep their "encodedBy" data. Wondering if it's a local vs. NAS issue or Linux vs. Windows (I'm on Linux).

--John
Interesting. Maybe it’s how you move them? I know that if SageTV sees the drive online but the file is missing it considers them gone. I wonder if copying first then deleting the originals helps or perhaps it’s just the opposite? Maybe moving is safer since it doesn’t see 2 copies at the same time which forces a new entry.

Do both of you “move” the files or do you copy then delete the original later?
__________________
Windows Installer
Reply With Quote
  #12  
Old 02-05-2022, 12:03 PM
graywolf's Avatar
graywolf graywolf is offline
Sage Icon
 
Join Date: Oct 2009
Location: NC
Posts: 1,370
This is the script I've been using forever. It runs via SJQ
I'll need to play around some other methods maybe.


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());
        }
    }
}
Reply With Quote
  #13  
Old 02-05-2022, 03:57 PM
jpwegas jpwegas is offline
Sage Expert
 
Join Date: May 2007
Posts: 500
Quote:
Originally Posted by wnjj View Post
Interesting. Maybe it’s how you move them? I know that if SageTV sees the drive online but the file is missing it considers them gone. I wonder if copying first then deleting the originals helps or perhaps it’s just the opposite? Maybe moving is safer since it doesn’t see 2 copies at the same time which forces a new entry.

Do both of you “move” the files or do you copy then delete the original later?
Normally I only move files when I need to migrate recordings off of a failing drive to a newer one.

My process is typically:
1. I leave Sage running BUT I do not add the new location as a recording directory yet. This is because it can take many hours to migrate the entire drive to the new one.
2. rsync (with the "archive" flag set) all data from old location to new location. The archive flag preserves the owner, modes, and timestamps on the files.
3. Shut down Sage when nothing is recording
4. rsync again just in case anything changed between #2 and #3 while Sage was running. rsync doesn't re-copy "unchanged" files so this step is usually very quick.
5. Edit Sage.properties and add the new drive location to seeker/video_storage. Remove the old location.
6. Start Sage again

So as you can see, this isn't the usual "nightly archive to slower media" that a lot of folks do.

--John
Reply With Quote
  #14  
Old 02-05-2022, 06:50 PM
wnjj wnjj is offline
Sage Icon
 
Join Date: Jan 2009
Posts: 1,484
Ok, so I found this comment in the code that calls into the function I linked above that creates “recovered” files:

Code:
          if (wiz.getFileForAiring(air) != null)
          {
            // This happens when the user moves files between video directories. The correct
            // way is to move things into a library import folder.
            // If these files on longer exist that are in that MediaFile then switch them to be this file
            MediaFile alternateMF = wiz.getFileForAiring(air);
__________________
Windows Installer
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Simple question on multiple tuners hagur SageTV Software 2 10-03-2010 04:00 PM
Question about disk i/o impact with multiple tuners sashimi Hardware Support 3 07-17-2008 10:05 AM
Multiple tuners, multiple extenders watching live streams tommymc General Discussion 4 07-03-2008 02:58 PM
Question about using multiple tuners with STB. ikurtram Hardware Support 1 04-20-2008 09:04 PM
Question on Multiple Tuners over network. rhsmcc SageTV Beta Test Software 1 05-22-2003 08:06 AM


All times are GMT -6. The time now is 01:54 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2022, vBulletin Solutions Inc.
Copyright 2003-2005 SageTV, LLC. All rights reserved.