Hi guys,
I have a video file which changes resolutions
(https://i.imgur.com/erIPsiv.png)
Does anyone know a way to turn this single file into multiple files (for example a 960x540 video file and a 1280x720) using avid or ffmpeg so I can edit it?
Thanks
Close Avidemux, delete the generated .idx2 index file and let Avidemux re-index the video. In admlog.txt from %localappdata%\avidemux\ directory, you will find one of more lines with "Size change" text. Note the hexadecimal value of offset where the change occurs. You need to split the MPEG-TS stream file at these offsets into separate files using a simple utility like head or dd which doesn't care about file content at all, then load/append matching file sets in Avidemux as separate videos.
I don't think ffmpeg will help here, but I may be wrong.
Hello guys,
I did read and appreciate your response all those months ago eumagga0x2a.
I didn't know much about video formats at the time and still dont.
Recently had to tackle this problem, I was able to cut videos using ffprobe to find out where the changes occur using this command (for anyone else interested) to get the keyframes:
ffprobe -hide_banner -skip_frame nokey -show_streams -select_streams v -show_entries frame=width,height,best_effort_timestamp_time -of json=compact=1 input.mp4
and ffmpeg to cut the vid (comes with problems, some of the cuts need re-encoding it seems) so I could edit the video (now videos with the same dimensions can be edited together) with avidemux.
I needed a simple drag and drop solution (loads of videos to edit) so I have a powershell script; i dont mind sharing if anyone else is interested.
Surprised this isn't more of a problem (videos changing resolution; e.g. when someone rotates their phone the resolution changes when recording a video?) worth tackling.
Are there other possible automated solutions?
I suppose I could just resize the whole video to the max resolution but it's not ideal.
Thanks!
Quote from: jimmyjim on September 17, 2022, 06:40:19 AMvideos changing resolution; e.g. when someone rotates their phone the resolution changes when recording a video?
Resolution doesn't change when a smartphone is rotated. Rotation state is only recorded in video metadata (ignored by Avidemux).
So far, no advances regarding handling of videos with variable dimensions in Avidemux compared to the state of affairs I described above.
>>I needed a simple drag and drop solution (loads of videos to edit) so I have a powershell script; i dont mind sharing if anyone else is interested.<<
I'd be very intersected in the script. I have several recordings of streams where the aspect ratio changes at the commercials.
Quote from: shmorgasbored773 on December 24, 2023, 03:09:35 AM>>I needed a simple drag and drop solution (loads of videos to edit) so I have a powershell script; i dont mind sharing if anyone else is interested.<<
I'd be very intersected in the script. I have several recordings of streams where the aspect ratio changes at the commercials.
This usually works pretty well, rename the file to clipRes.ps1 or something
clipRes "file1.ts", "file2.ts"
edit: i dont think the attachment can be downloaded? here it is:
function launchProcess{
Param(
[String]$pathToExe,
[Object]$processargs
)
Process{
$ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
$ProcessInfo.FileName = $pathToExe
$ProcessInfo.RedirectStandardError = $true
$ProcessInfo.RedirectStandardOutput = $true
$ProcessInfo.UseShellExecute = $false
$ProcessInfo.Arguments = $processargs
#$processinfo.CreateNoWindow=$true
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo = $ProcessInfo
$Process.Start() | Out-Null
$Process #return the process
}
}
function getFrameData{
Param(
[String]$pathToVid
)
Process{
$fileName=[System.IO.Path]::GetFileNameWithoutExtension($pathToVid)
$fileDataPath=[System.IO.Path]::GetDirectoryName($pathToVid)+"\$fileName.json"
if([System.IO.File]::Exists($fileDataPath)){
$data= Get-Content $fileDataPath | convertfrom-json
}
else {
write-host "Gathering key frame info"
$processargs=@("-hide_banner", "-skip_frame", "nokey", "-show_streams", "-select_streams", "v", "-show_entries", "frame=width,height,best_effort_timestamp_time", "-of", "json=compact=1", "", """$pathToVid""")
$Process=launchProcess $pathToFFProbeExe $processargs
$data=$Process.StandardOutput.ReadToEnd() | ConvertFrom-Json
# add a property for the clips that will be generated
$data | Add-Member -name 'clips' -Value @() -MemberType NoteProperty
$data | Add-Member -name 'saved' -Value $false -MemberType NoteProperty
$data | Add-Member -name 'fileDataPath' -Value $fileDataPath -MemberType NoteProperty
}
$data
}
}
function cutVideo{
Param(
[String]$sourceFile,
[String]$outputFile,
[double]$startTime,
[Object]$endTime,
[int]$width,
[int]$height
)
Process{
$params=@("-hide_banner","-loglevel", "error","-ss", "$startTime","-to", "$endTime", "-i", """$pathToVid""")
$params+=@("-aspect", "$($width):$($height)")
$params+=@("-c", "copy")
$params+="""$outputFile"""
$process=start-process $pathToFFMpegExe -PassThru -ArgumentList $params -NoNewWindow
#($process=start-process $pathToFFMpegExe -PassThru -ArgumentList $params -NoNewWindow).PriorityClass = [System.Diagnostics.ProcessPriorityClass]::BelowNormal
#$process.ProcessorAffinity=0x3
Wait-Process -inputobject $process
}
}
function Get-Clips{
Param(
[Object]$data
)
Process{
$newResFrame=[PSCustomObject]@{
best_effort_timestamp_time=0#$data.frames[0].best_effort_timestamp_time
height=$data.streams[0].height
width=$data.streams[0].width
}
$count=0
while($count -lt $data.frames.count){
$frame=$data.frames[$count]
if(($frame.width -ne $newResFrame.width `
-and $frame.height -ne $newResFrame.height) -or ($count+1)-eq$data.frames.count){
$lastFrame=$null; #the last frame
if(($count+1)-ne$data.frames.count){
# not at the end of the file, so check the non key frames for the change of size
<#$startInt=$data.frames[$count-1].best_effort_timestamp_time
$secondsToCheck=$frame.best_effort_timestamp_time-$startInt
$processargs=@("-hide_banner", "-show_streams", "-select_streams", "v", "-show_entries", "frame=width,height,best_effort_timestamp_time", "-read_intervals", "$startInt%+$secondsToCheck","-of", "json=compact=1", "", """$pathToVid""")
$Process=launchProcess $pathToFFProbeExe $processargs
$datal=$Process.StandardOutput.ReadToEnd() | ConvertFrom-Json
$lastFrame=$datal.frames[-2]
#look for the time it changes
foreach($item in $data){
if($item.width -ne $newResFrame.width -and $item.height -ne $newResFrame.height){
$lastFrame=$item
break
}
}#>
$lastFrame=$data.frames[$count-2]
}
else{
$lastFrame=$data.frames[-1]
}
# save so we dont do this loop again if we reload
$data.clips+=[PSCustomObject]@{
height=$newResFrame.height
width=$newResFrame.width
startTimestamp=$newResFrame.best_effort_timestamp_time
endTimeStamp=$lastFrame.best_effort_timestamp_time
}
$newResFrame=$frame
}
++$count
}
}
}
$pathToFFMpegExe=&where.exe ffmpeg
$pathToFFProbeExe=$pathToFFMpegExe.replace("ffmpeg.exe", "ffprobe.exe")
$outputExt="ts"
if($args[0] -eq ""){exit}
$files=$args[0] -split ", "
foreach($file in $files){
$pathToVid=$file
$fileName=[System.IO.Path]::GetFileNameWithoutExtension($pathToVid)
$data=getFrameData -pathToVid $pathToVid
# sort the video into clips of same res
if($data.clips.Count -eq 0){
Get-Clips -data $data
}
if($data.clips.Count -eq 1){
write-host "1 clip found, skipping"
}
else{
Write-Host $data.clips.Count"clips being created"
$count=0
while($count -lt $data.clips.Count){
$widthHeightStr=""
if($data.clips[$count].width -ne $data.streams[0].width `
-and $data.clips[$count].height -ne $data.streams[0].height){
$widthHeightStr=" $($data.clips[$count].width)x$($data.clips[$count].height)"
}
$outputFile=[System.IO.Path]::GetDirectoryName($pathToVid)+"\"+"$fileName $($count+1)$widthHeightStr.$outputExt"
$endTime=$data.clips[$count].endTimeStamp
cutVideo -sourceFile $pathToVid -outputFile $outputFile -startTime $data.clips[$count].startTimestamp -endTime $endTime -width $data.clips[$count].width -height $data.clips[$count].height
++$count
}
}
if($data.saved -ne $true){
$data.saved=$true
$data | convertto-json -WarningAction SilentlyContinue | out-file -filepath $data.fileDataPath
}
}
You can drag files onto this .bat if you name it the same as the powershell script, e.g. clipRes.ps1 and clipRes.bat instead of typing
@echo off
rem the name of the script is drive path name of the Parameter %0
rem (= the batch file) but with the extension ".ps1"
set PSScript=%~dpn0.ps1
set args=%1
:More
shift
if '%1'=='' goto Done
set args=%args%, %1
goto More
:Done
pwsh -NoExit -Command "& '%PSScript%' '%args%'"
Regarding download of attachments: The server the forum runs on doesn't work with http2. Disable the protocol (AKA spdy) via the advanced settings of Firefox. I am not aware of other browsers allowing to do that.