diff --git a/Get-VideoInfo.ini b/Get-VideoInfo.ini index 26e99bf..1423538 100644 --- a/Get-VideoInfo.ini +++ b/Get-VideoInfo.ini @@ -2,6 +2,7 @@ Text_Prompt=prompt Model=type Resolution=resolution Number_of_frames=video_length +Video_Length=frames_count Seed=seed Frames_Positions=frames_positions Guidance=guidance_scale diff --git a/Get-VideoInfo.ps1 b/Get-VideoInfo.ps1 index 1a85583..8475ecc 100644 --- a/Get-VideoInfo.ps1 +++ b/Get-VideoInfo.ps1 @@ -9,7 +9,9 @@ When present, outputs the parsed comment metadata as JSON. .DESCRIPTION This script uses ffprobe to extract video format metadata, parses the comment tag as JSON, - and outputs the structured information with proper error handling. + and outputs the structured information with proper error handling. Fields configured as + 'frames_count' in the INI file are read directly from ffprobe (actual encoded frame count) + rather than from the JSON metadata. #> param( [Parameter(Mandatory = $true)] @@ -148,63 +150,78 @@ try { $displayNameFormatted = $displayName -replace '_', ' ' - $fieldExists = $parsedComment.PSObject.Properties.Name -contains $jsonFieldName - - if (-not $fieldExists) { - $valueDisplay = 'Not found' - } - else { - $fieldValue = $parsedComment.$jsonFieldName - - if ($null -eq $fieldValue) { - $valueDisplay = 'Not found' - } - elseif ($jsonFieldName -eq 'generation_time') { - $totalSeconds = [int]$fieldValue - $minutes = [Math]::Floor($totalSeconds / 60) - $seconds = $totalSeconds % 60 - $valueDisplay = ('{0}s ({1}m {2}s)' -f $totalSeconds, $minutes, $seconds) - } - elseif ($jsonFieldName -eq 'creation_date') { - try { - $dateTime = [DateTime]::Parse($fieldValue) - $valueDisplay = $dateTime.ToString('yyyy-MM-dd HH:mm:ss') - } - catch { - $valueDisplay = $fieldValue -replace 'T', ' ' - } - } - elseif ($jsonFieldName -eq 'video_length') { - # Always use the real frame rate reported by ffprobe for the - # duration calculation. The JSON metadata's force_fps may be a - # non-numeric mode marker (e.g. "control") or simply not match - # the actual encoded frame rate. - $fps = if ($actualFps) { $actualFps } else { 24.0 } - $frames = [int]$fieldValue + if ($jsonFieldName -eq 'frames_count') { + # frames_count is read directly from ffprobe (actual encoded frame count) + # rather than from the JSON comment metadata. + $fps = if ($actualFps) { $actualFps } else { 24.0 } + $ffFrames = & ffprobe -v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames -of csv=p=0 -- "$VideoPath" 2>&1 | Select-Object -First 1 + if ($ffFrames -and $ffFrames -match '^\d+$') { + $frames = [int]$ffFrames $durationSeconds = [Math]::Round($frames / $fps, 1) $valueDisplay = ('{0} frames ({1}s, {2} fps)' -f $frames, $durationSeconds, $fps) + } else { + $valueDisplay = 'Not found' } - elseif ($fieldValue -is [array]) { - if ($fieldValue.Count -gt 1) { - # Pretty-print array values as JSON, prefixed with a newline so the - # multi-line output starts cleanly under the field label. - $jsonArray = $fieldValue | ConvertTo-Json -Depth 10 - $valueDisplay = [Environment]::NewLine + $jsonArray - } - else { - $jsonArray = $fieldValue | ConvertTo-Json -Depth 10 -Compress - $valueDisplay = $jsonArray - } + } + else { + $fieldExists = $parsedComment.PSObject.Properties.Name -contains $jsonFieldName + + if (-not $fieldExists) { + $valueDisplay = 'Not found' } else { - $valueDisplay = $fieldValue - # If the value looks like a WxH resolution string and ffprobe - # reports a different actual encoded resolution, surface both. - if ($actualResolution ` - -and ($fieldValue -is [string]) ` - -and ($fieldValue -match '^\d+x\d+$') ` - -and ($fieldValue -ne $actualResolution)) { - $valueDisplay = "$fieldValue (real: $actualResolution)" + $fieldValue = $parsedComment.$jsonFieldName + + if ($null -eq $fieldValue) { + $valueDisplay = 'Not found' + } + elseif ($jsonFieldName -eq 'generation_time') { + $totalSeconds = [int]$fieldValue + $minutes = [Math]::Floor($totalSeconds / 60) + $seconds = $totalSeconds % 60 + $valueDisplay = ('{0}s ({1}m {2}s)' -f $totalSeconds, $minutes, $seconds) + } + elseif ($jsonFieldName -eq 'creation_date') { + try { + $dateTime = [DateTime]::Parse($fieldValue) + $valueDisplay = $dateTime.ToString('yyyy-MM-dd HH:mm:ss') + } + catch { + $valueDisplay = $fieldValue -replace 'T', ' ' + } + } + elseif ($jsonFieldName -eq 'video_length') { + # Always use the real frame rate reported by ffprobe for the + # duration calculation. The JSON metadata's force_fps may be a + # non-numeric mode marker (e.g. "control") or simply not match + # the actual encoded frame rate. + $fps = if ($actualFps) { $actualFps } else { 24.0 } + $frames = [int]$fieldValue + $durationSeconds = [Math]::Round($frames / $fps, 1) + $valueDisplay = ('{0} frames ({1}s, {2} fps)' -f $frames, $durationSeconds, $fps) + } + elseif ($fieldValue -is [array]) { + if ($fieldValue.Count -gt 1) { + # Pretty-print array values as JSON, prefixed with a newline so the + # multi-line output starts cleanly under the field label. + $jsonArray = $fieldValue | ConvertTo-Json -Depth 10 + $valueDisplay = [Environment]::NewLine + $jsonArray + } + else { + $jsonArray = $fieldValue | ConvertTo-Json -Depth 10 -Compress + $valueDisplay = $jsonArray + } + } + else { + $valueDisplay = $fieldValue + # If the value looks like a WxH resolution string and ffprobe + # reports a different actual encoded resolution, surface both. + if ($actualResolution ` + -and ($fieldValue -is [string]) ` + -and ($fieldValue -match '^\d+x\d+$') ` + -and ($fieldValue -ne $actualResolution)) { + $valueDisplay = "$fieldValue (real: $actualResolution)" + } } } }