Recordings filename pattern (use the custom label)

An evolving, supported alternative to Rovi
Forum rules
★ Download the latest EPG123 here: http://epg123.garyan2.net <> Setup guide here: http://epg123.garyan2.net/downloads/epg123_Guide.pdf
NOYB

Posts: 36
Joined: Thu Sep 10, 2020 8:03 am
Location:

HTPC Specs: Show details

Re: Recordings filename pattern (use the custom label)

#21

Post by NOYB » Sat Sep 26, 2020 9:34 pm

If it works like I think it does, an option to use the Service Callsign as Service Name and/or Call Sign might be nice.

User avatar
garyan2

Posts: 5344
Joined: Fri Nov 27, 2015 7:23 pm
Location:

HTPC Specs: Show details

#22

Post by garyan2 » Sat Sep 26, 2020 11:03 pm

NOYB wrote:
Sat Sep 26, 2020 9:34 pm
If it works like I think it does, an option to use the Service Callsign as Service Name and/or Call Sign might be nice.
Not quite that simple, but of course doable. The MergedChannel, which is what is displayed on the left side of the client, consists of a primary channel and any number of secondary channels. At the end of a TV Setup scan, the primary channel is the tuner channel from the "Scanned Lineup". When guide listings are assigned to the merged channel, the listings take the primary channel position and the tuner channel gets moved to the secondary channels. If that is all that is done with your setup, it can be done fairly easily.

When a user merges or splits channels and tuners, or changes priority of the tuners within a merged channel, then things get a little complicated with multiple scanned channels in the secondary or tuning overrides created within the WMC database. Gets a little weird and can be difficult to trace.

What I currently have for copying to the clipboard is closer to an engineering lash-up rather than something that could be production worthy. If the merged channel primary is guide listings, I just look at the first channel in the merged channel secondary and if it is from a scanned lineup I use its' call sign. I don't look at any other secondary channels nor do I check the tuning overrides to find where the scanned channel may be. I think the best/easiest thing I could do would be to provide a command line parameter to do this, but it would only be used during the automatch procedure when mapping guide listings to a channel that has the scanned channel in the merged channel primary channel. I would read the scanned channel call sign, assign the guide listings to the merged channel which will become the primary channel, and assign a custom call sign using the captured scanned channel call sign.
- Gary
Keeping WMC alive beyond January 2020. http://epg123.garyan2.net

NOYB

Posts: 36
Joined: Thu Sep 10, 2020 8:03 am
Location:

HTPC Specs: Show details

#23

Post by NOYB » Mon Sep 28, 2020 10:29 am

The script to auto-magically collect the PSIP VCT short names from HDHomeRun device and customize the config has learned some new things.

Learned how to run HDHomeRun device channel detection scan
Learned to operate standalone (without a HDHR device) using guide number and name JSON data.
Learned to do a dry run
Factored into functions

C:\ProgramData\GaRyan2\epg123\custom_callSign_serviceName.ps1

Code: Select all

# Version: 20200928.1-alpha
# Status: alpha

# Standard file system locations
# Folder: C:\ProgramData\GaRyan2\epg123
# PS Script File: custom_callSign_serviceName.ps1
# JSON Data File: custom_callSign_serviceName.json
# Dry Run CFG File: custom_callSign_serviceName.Dry_Run.cfg

# Development environment:
# Windows 8.1 Pro w/Media Center
# PowerShell: 4.0
# SiliconDust: HDHomeRun CONNECT, Model: HDHR4-2US, Firmware: 20200907


# Criteria to use
$Dry_Run = $true								# Save to $EPG_Data_Dir'\custom_callSign_serviceName.Dry_Run.cfg'
$ChLineUp = 'USA-OTA-97007'						# Channel line up associated with HDHomeRun device
$EPG_Service = 'EPG123'							# EPG service name

$EPG_Data_Dir = 'C:\ProgramData\GaRyan2\epg123'	# Fully qualified EPG data dir path (without trailing slash)
$CFG_File = 'epg123.cfg'						# EPG config file
$MXF_File = 'epg123.mxf'						# EPG MXF file

$Custom_CallSign_flag = $true					# Set/Replace (true), Remove (false) custom channel call sign
$Custom_Service_Name_flag = $true				# Set/Replace (true), Remove (false) custom channel service name

# Can be used standalone with guide name and number JSON data: ex: [{"GuideNumber":"10.4","GuideName":"OPBKids"}]
$Retrive_Data_From_Device = $true				# Retrieve channels & names from HDHomeRun device
$Device_Channel_Dectection_Scan = $false		# Perform HDHomeRun device channel detection scan
#$Device_ID = '1040dddd'						# HDHomeRun device ID (only for client utility scan)
$Device_Address = '192.168.2.202'				# HDHomeRun device address
$Show = 'found'									# HDHomeRun device channel line up query: all, found, favorites
# End Criteria to use


function Invoke-Main {
	Get-Channels_Service_Name_Data
	Edit-Configuration
}


#
# Retrieve PSIP VCT short name from HDHomeRun device.  Or use default/fallback channel names.
#
function Get-Channels_Service_Name_Data {

	if ($Retrive_Data_From_Device) {
		$webclient = new-object System.Net.WebClient
		$lineup_json_url = 'http://'+$Device_Address+'/lineup.json?show='+$Show
		if ($Device_Channel_Dectection_Scan) {
			Invoke-Device_Channel_Dectection_Scan_Web
#			Invoke-Device_Channel_Dectection_Scan_Utility	# SliconDust hdhomerun_config.exe
		} else {
			$json = $webclient.DownloadString($lineup_json_url)
		}
	}

	try {
		$vPSObject = $json | ConvertFrom-Json -ErrorAction Stop;
		'Using data retrieved from device ('+$Device_Address+')'
		''	# Blank line

		# Save device retrieved, guide number and guide name abbreviated, json for default/fallback, don't overwrite existing
		if (!(Test-Path $EPG_Data_Dir'\custom_callSign_serviceName.json')) {
			$json = $json -Replace '\[\{', "[`r`n{" -Replace '},{', "},`r`n{" -Replace '}]', "}`r`n]"	# Line-ized
			$json = $json -Replace "({`"GuideNumber.*?GuideName`":`".*?`").*(},*)", "`$1`$2"			# Only GuideNumber and GuideName
			$json | Set-Content -Path $EPG_Data_Dir'\custom_callSign_serviceName.json'
		}
	} catch {
		# Channel GuideNumber and GuideName json.
		# Use in place of (retrieve from device false) or if HDHomeRun device query fails.
		if (Test-Path $EPG_Data_Dir'\custom_callSign_serviceName.json') {
			$json_fallback = Get-Content -path $EPG_Data_Dir'\custom_callSign_serviceName.json' -Raw
			$vPSObject = $json_fallback | ConvertFrom-Json
			'Using default/fallback data: '
			$EPG_Data_Dir+'\custom_callSign_serviceName.json'
			''	# Blank line
		} else {
			'Default/Fallback data not found: '
			$EPG_Data_Dir+'\custom_callSign_serviceName.json'
			''	# Blank line
			pause
			exit
		}
	}

	$script:vPSObject = $vPSObject
}


#
# Set/Remove/Replace epg123.cfg customServiceName and customCallSign fields
#
function Edit-Configuration {

	$epg123_cfg = Get-Content -path $EPG_Data_Dir'\'$CFG_File -Raw
	$epg123_mxf = Get-Content -path $EPG_Data_Dir'\output\'$MXF_File -Raw

	"Channel`tName`tSign`tSta ID`tLineup`tSrv ID"
	foreach ($ch in $vPSObject) {

		$ChNumber = $ch.GuideNumber.Split('.')
		$ChName = $ch.GuideName
		$ChCallSign = $ch.GuideName

		# Get EPG channel lineup station ID, and perform Set/Remove/Replace
		if ( $epg123_mxf -match `
			"<Channel uid=`"!Channel!$ChLineUp!(?<station_id>[0-9]*)_"+$ChNumber[0]+"_"+$ChNumber[1]+"`" lineup=`"(?<lineup_id>l[0-9]*)`" " + `
			"service=`"(?<service_id>.*?)`" number=`""+$ChNumber[0]+"`" subNumber=`""+$ChNumber[1]+"`" />" ) {

			$station_id = $matches['station_id'];	$RegexEscaped_station_id = [Regex]::Escape($station_id)
			$lineup_id = $matches['lineup_id'];		$RegexEscaped_lineup_id = [Regex]::Escape($lineup_id)
			$service_id = $matches['service_id'];	$RegexEscaped_service_id = [Regex]::Escape($service_id)

			# Get existing custom service name string
			$cSN = ( $epg123_cfg -match "<StationID CallSign=`".*?`".*?(?<Existing_customServiceName> customServiceName=`".*?`").*?>$RegexEscaped_station_id</StationID>" )
			$Existing_customServiceName = $matches['Existing_customServiceName'];		$RegexEscaped_Existing_customServiceName = [Regex]::Escape($Existing_customServiceName)

			# Get existing custom call sign string
			$cCS = ( $epg123_cfg -match "<StationID CallSign=`".*?`".*?(?<Existing_customCallSign> customCallSign=`".*?`").*?>$RegexEscaped_station_id</StationID>" )
			$Existing_customCallSign = $matches['Existing_customCallSign'];				$RegexEscaped_Existing_customCallSign = [Regex]::Escape($Existing_customCallSign)

			if ($Custom_Service_Name_flag) { $customServiceName = " customServiceName=`"$ChName`"" }
			if ($Custom_CallSign_flag) { $customCallSign = " customCallSign=`"$ChCallSign`"" }

			# Set/Remove/Replace custom service name
			$epg123_cfg = $epg123_cfg -replace `
				"<StationID CallSign=`"(.*?)`"(.*?)$RegexEscaped_Existing_customServiceName(.*?)>$RegexEscaped_station_id</StationID>", `
				"<StationID CallSign=`"`$1`"`$2$customServiceName`$3>$station_id</StationID>"

			# Set/Remove/Replace custom call sign
			$epg123_cfg = $epg123_cfg -replace `
				"<StationID CallSign=`"(.*?)`"(.*?)$RegexEscaped_Existing_customCallSign(.*?)>$RegexEscaped_station_id</StationID>", `
				"<StationID CallSign=`"`$1`"`$2$customCallSign`$3>$station_id</StationID>"

			$ChNumber[0]+'.'+$ChNumber[1]+"`t"+$ChName+"`t"+$ChCallSign+"`t"+$station_id+"`t"+$lineup_id+"`t"+$service_id
		}
	}

	''	# Blank line
	'Customized epg123.cfg saved to: '
	if ($Dry_Run) {
		$EPG_Data_Dir+'\custom_callSign_serviceName.Dry_Run.cfg'
		$epg123_cfg.TrimEnd() | Set-Content -Encoding UTF8 -Path $EPG_Data_Dir'\custom_callSign_serviceName.Dry_Run.cfg'
	} else {
		$EPG_Data_Dir+'\'+$CFG_File
		$epg123_cfg.TrimEnd() | Set-Content -Encoding UTF8 -Path $EPG_Data_Dir'\'$CFG_File
	}
}


#
# Run HDHomeRun device channel scan (web based)
#
function Invoke-Device_Channel_Dectection_Scan_Web {

	$status_json_url = 'http://'+$Device_Address+'/lineup_status.json'

	$scan_status = $webclient.DownloadString($status_json_url) | ConvertFrom-Json
	if ($scan_status.ScanInProgress -eq 0) {
		if ($scan_status.ScanPossible -eq 1) {
			'Channel Detection: '
			' Scanning device ('+$Device_Address+')...'
			$lineup_scan_start_url = 'http://'+$Device_Address+'/lineup.post?scan=start&source='+$scan_status.Source
#			Invoke-WebRequest -Uri $lineup_scan_start_url -Method POST
			$webclient.UploadString($lineup_scan_start_url,'')
		} else { 'Scan not possible.  May not be an available tuner.' }
	} else { 'Channel detection scan already in progress...' }

	# While scanning...
	Do {
		$scan_status = $webclient.DownloadString($status_json_url) | ConvertFrom-Json
		if ($scan_status.ScanInProgress -ge 1) {
			$status = 'Found '+$scan_status.Found+' programs ('+$scan_status.Progress+'%)'
			Write-Host "`r"$status -NoNewLine
			Start-Sleep 1
		}
	} While ( $scan_status.ScanInProgress -eq 1)

	$json = $webclient.DownloadString($lineup_json_url)

	# Final status
	$Found = ($json | ConvertFrom-Json).length; $Progress = 100
	$status = "Found "+$Found+" programs ("+$Progress+"%)"
	Write-Host "`r"$status
	''	# Blank line

	$script:json = $json
}


#
# Run HDHomeRun device channel scan; Return GuideNumber and GuideName JSON string (client utility based)
#
function Invoke-Device_Channel_Dectection_Scan_Utility {
	$tuner0 = & 'C:\Program Files\Silicondust\HDHomeRun\hdhomerun_config.exe' $Device_ID get /tuner0/status
	$tuner1 = & 'C:\Program Files\Silicondust\HDHomeRun\hdhomerun_config.exe' $Device_ID get /tuner1/status

	"Scanning device $Device_ID for channels..."
	if ($tuner0 -match "lock=none") {
		$channel_scan = & 'C:\Program Files\Silicondust\HDHomeRun\hdhomerun_config.exe' $Device_ID 'scan' '/tuner0'
		$Device_Channel_Dectection_Scan_Status = & 'C:\Program Files\Silicondust\HDHomeRun\hdhomerun_config.exe' $Device_ID 'get' '/lineup/scan'
	} elseif ($tuner1 -match "lock=none") {
		$channel_scan = & 'C:\Program Files\Silicondust\HDHomeRun\hdhomerun_config.exe' $Device_ID 'scan' '/tuner1'
		$Device_Channel_Dectection_Scan_Status = & 'C:\Program Files\Silicondust\HDHomeRun\hdhomerun_config.exe' $Device_ID 'get' '/lineup/scan'
	} else {
		"No Tuner Available"
	}

	if ($Device_Channel_Dectection_Scan_Status -match "state=complete") {
		$json = '['
		$lines = $channel_scan.split("`r`n")
		foreach ($line in $lines) {
			$matched = $line -match "PROGRAM *[0-9]*: *(?<GuideNumber>[0-9]{1,2}\.[0-9]*) *(?<GuideName>.*)"
			if ($matched) {
				$json += '{"GuideNumber":"'+$matches['GuideNumber']+'","GuideName":"'+$matches['GuideName']+'"},'
			}
		}
		$json = $json.TrimEnd(',')
		$json += ']'
	}

	# Sort by ascending GuideNumber
	$array = $json | ConvertFrom-Json
	$array_sorted = $array | Sort-Object { [float]$_.GuideNumber }
	$json = $array_sorted | ConvertTo-Json
	$json = $json -Replace "[`r`n]","" -Replace " *{ *","{" -Replace " *} *", "}" -Replace "`": *`"","`":`"" -Replace "`", *`"","`",`""

	$script:json = $json
}


Invoke-Main

''	# Blank line
pause	# Wait for user to exit/close PS window



# NOTE:
# $json = Invoke-WebRequest http://$Device_Address/lineup.json?show=found		# Doesn't work with UTF8 encoding

# Workaround A
# $json = Invoke-WebRequest -Uri 'http://$Device_Address/lineup.json?show=found' -Outfile $EPG_Data_Dir'\hdhrlineup.json'
# $json = Get-Content -Path $EPG_Data_Dir'\hdhrlineup.json' -Encoding UTF8 -Raw
# Remove-Item -Path $EPG_Data_Dir'\hdhrlineup.json' -Force

# Workaround B
# $webclient = new-object System.Net.WebClient
# $json = $webclient.DownloadString("http://$Device_Address/lineup.json?show=$Show")
C:\ProgramData\GaRyan2\epg123\custom_callSign_serviceName.json

Code: Select all

[
{"GuideNumber":"2.1","GuideName":"KATU"},
{"GuideNumber":"2.2","GuideName":"MeTV"},
{"GuideNumber":"2.3","GuideName":"Comet"},
{"GuideNumber":"2.4","GuideName":"Stadium"},
{"GuideNumber":"6.1","GuideName":"KOIN-HD"},
{"GuideNumber":"6.2","GuideName":"GetTV"},
{"GuideNumber":"6.3","GuideName":"Bounce"},
{"GuideNumber":"8.1","GuideName":"KGW"},
{"GuideNumber":"8.2","GuideName":"Crime"},
{"GuideNumber":"8.3","GuideName":"Quest"},
{"GuideNumber":"8.10","GuideName":"KGW"},
{"GuideNumber":"8.20","GuideName":"Crime"},
{"GuideNumber":"8.30","GuideName":"Quest"},
{"GuideNumber":"10.1","GuideName":"OPB"},
{"GuideNumber":"10.2","GuideName":"OPBPlus"},
{"GuideNumber":"10.3","GuideName":"OPBKids"},
{"GuideNumber":"10.4","GuideName":"OPB-FM"},
{"GuideNumber":"12.1","GuideName":"FOX 12"},
{"GuideNumber":"12.2","GuideName":"COZI"},
{"GuideNumber":"12.3","GuideName":"LAFF"},
{"GuideNumber":"12.4","GuideName":"DABL"},
{"GuideNumber":"22.1","GuideName":"ION"},
{"GuideNumber":"22.2","GuideName":"qubo"},
{"GuideNumber":"22.3","GuideName":"IONPlus"},
{"GuideNumber":"22.4","GuideName":"Shop"},
{"GuideNumber":"22.5","GuideName":"QVC"},
{"GuideNumber":"22.6","GuideName":"HSN"},
{"GuideNumber":"22.7","GuideName":"TLMD"},
{"GuideNumber":"24.1","GuideName":"TBN HD"},
{"GuideNumber":"24.2","GuideName":"Hilsong"},
{"GuideNumber":"24.3","GuideName":"SMILE"},
{"GuideNumber":"24.4","GuideName":"Enlace"},
{"GuideNumber":"24.5","GuideName":"POSITIV"},
{"GuideNumber":"26.1","GuideName":"SBN TV"},
{"GuideNumber":"26.2","GuideName":"Shop LC"},
{"GuideNumber":"26.3","GuideName":"ACE TV"},
{"GuideNumber":"26.4","GuideName":"Heartla"},
{"GuideNumber":"32.1","GuideName":"KRCW"},
{"GuideNumber":"32.2","GuideName":"Antenna"},
{"GuideNumber":"32.3","GuideName":"Courttv"},
{"GuideNumber":"32.4","GuideName":"TBD"},
{"GuideNumber":"47.1","GuideName":"KUNP-LD"},
{"GuideNumber":"47.2","GuideName":"TBD"},
{"GuideNumber":"47.3","GuideName":"Charge"},
{"GuideNumber":"49.1","GuideName":"Fox12+"},
{"GuideNumber":"49.2","GuideName":"Escape"},
{"GuideNumber":"49.3","GuideName":"Bounce"},
{"GuideNumber":"49.4","GuideName":"Grit"},
{"GuideNumber":"49.20","GuideName":"Escape"},
{"GuideNumber":"49.40","GuideName":"Grit"}
]

Post Reply