lincruste

Powershell video resizer FFMPEG

Nov 10th, 2025
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PowerShell 7.54 KB | Software | 0 0
  1. Add-Type -AssemblyName PresentationFramework
  2. Add-Type -AssemblyName System.Windows.Forms
  3.  
  4. # Déterminer le dossier du script et localiser ffmpeg/ffprobe
  5. try {
  6.     $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
  7. } catch {
  8.     $scriptDir = Get-Location
  9. }
  10. $ffmpegCmd  = Join-Path $scriptDir "ffmpeg.exe"
  11. $ffprobeCmd = Join-Path $scriptDir "ffprobe.exe"
  12.  
  13. # Vérifier la présence de ffmpeg/ffprobe
  14. if (-not (Test-Path $ffmpegCmd)) {
  15.     [System.Windows.MessageBox]::Show("ffmpeg.exe est introuvable dans le dossier du script.")
  16.     exit
  17. }
  18. if (-not (Test-Path $ffprobeCmd)) {
  19.     [System.Windows.MessageBox]::Show("ffprobe.exe est introuvable dans le dossier du script.")
  20.     exit
  21. }
  22.  
  23. # Créer la fenêtre WPF
  24. [xml]$xaml = @"
  25. <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  26.        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  27.        Title="Convertisseur vidéo (H.264 + AAC)" Height="500" Width="650"
  28.        WindowStartupLocation="CenterScreen" ResizeMode="NoResize" Background="#202020">
  29.     <Grid Margin="15">
  30.         <Grid.RowDefinitions>
  31.             <RowDefinition Height="Auto"/>
  32.             <RowDefinition Height="Auto"/>
  33.             <RowDefinition Height="Auto"/>
  34.             <RowDefinition Height="Auto"/>
  35.             <RowDefinition Height="*"/>
  36.             <RowDefinition Height="Auto"/>
  37.         </Grid.RowDefinitions>
  38.         <TextBlock Grid.Row="0" Text="Fichier vidéo :" Foreground="White" Margin="0,0,0,5"/>
  39.         <StackPanel Grid.Row="1" Orientation="Horizontal">
  40.             <TextBox x:Name="InputFile" Width="450" Margin="0,0,5,0"/>
  41.             <Button x:Name="BrowseButton" Content="Parcourir..." Width="120"/>
  42.         </StackPanel>
  43.         <StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,10,0,0">
  44.             <TextBlock Text="Redimensionnement (%) :" Foreground="White" VerticalAlignment="Center"/>
  45.             <TextBox x:Name="ResizePercent" Width="60" Margin="10,0,0,0" Text="100"/>
  46.         </StackPanel>
  47.         <StackPanel Grid.Row="3" Orientation="Horizontal" Margin="0,10,0,0">
  48.             <CheckBox x:Name="OverwriteCheckbox" Content="Écraser le fichier existant" Foreground="White"/>
  49.         </StackPanel>
  50.         <TextBox x:Name="OutputLog" Grid.Row="4" Margin="0,10,0,10" AcceptsReturn="True"
  51.                  VerticalScrollBarVisibility="Auto" Background="#101010" Foreground="#00FF00" FontFamily="Consolas"/>
  52.         <Button x:Name="ConvertButton" Grid.Row="5" Content="Convertir" Width="120" Height="30"
  53.                 HorizontalAlignment="Right" Margin="0,10,0,0"/>
  54.     </Grid>
  55. </Window>
  56. "@
  57.  
  58. # Charger le XAML
  59. $reader = New-Object System.Xml.XmlNodeReader $xaml
  60. $window = [Windows.Markup.XamlReader]::Load($reader)
  61.  
  62. # Associer les contrôles
  63. $BrowseButton = $window.FindName("BrowseButton")
  64. $InputFile = $window.FindName("InputFile")
  65. $ResizePercent = $window.FindName("ResizePercent")
  66. $OutputLog = $window.FindName("OutputLog")
  67. $ConvertButton = $window.FindName("ConvertButton")
  68. $OverwriteCheckbox = $window.FindName("OverwriteCheckbox")
  69.  
  70. # Fonction pour journaliser dans la zone de texte
  71. function Add-LogLine {
  72.    param($text)
  73.    $OutputLog.AppendText("$text`r`n")
  74.    $OutputLog.ScrollToEnd()
  75. }
  76.  
  77. # Parcourir un fichier
  78. $BrowseButton.Add_Click({
  79.    $ofd = New-Object System.Windows.Forms.OpenFileDialog
  80.    $ofd.Filter = "Fichiers vidéo|*.mp4;*.mkv;*.avi;*.mov;*.flv;*.wmv;*.webm|Tous les fichiers|*.*"
  81.    if ($ofd.ShowDialog() -eq "OK") {
  82.        $InputFile.Text = $ofd.FileName
  83.    }
  84. })
  85.  
  86. # Conversion
  87. $ConvertButton.Add_Click({
  88.    $file = $InputFile.Text
  89.    if (-not (Test-Path $file)) {
  90.        [System.Windows.MessageBox]::Show("Veuillez sélectionner un fichier vidéo valide.")
  91.        return
  92.    }
  93.    
  94.    $percent = [int]$ResizePercent.Text
  95.    if ($percent -le 0) { $percent = 100 }
  96.    
  97.    Add-LogLine "Lecture des dimensions de la vidéo..."
  98.    
  99.    # Lire les dimensions avec ffprobe
  100.    $psi = New-Object System.Diagnostics.ProcessStartInfo
  101.    $psi.FileName = $ffprobeCmd
  102.    $psi.Arguments = "-v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 `"$file`""
  103.     $psi.UseShellExecute = $false
  104.     $psi.RedirectStandardOutput = $true
  105.     $psi.RedirectStandardError = $true
  106.     $psi.CreateNoWindow = $true
  107.    
  108.     $process = New-Object System.Diagnostics.Process
  109.     $process.StartInfo = $psi
  110.     $process.Start() | Out-Null
  111.     $dimensions = $process.StandardOutput.ReadToEnd().Trim()
  112.     $process.WaitForExit()
  113.    
  114.     if (-not $dimensions -or $dimensions -eq "") {
  115.         Add-LogLine "Erreur : impossible de lire les dimensions."
  116.         return
  117.     }
  118.    
  119.     $dims = $dimensions -split ","
  120.     $width = [int]$dims[0]
  121.     $height = [int]$dims[1]
  122.    
  123.     $newWidth = [int]($width * $percent / 100)
  124.     $newHeight = [int]($height * $percent / 100)
  125.    
  126.     # Arrondir à un nombre pair pour éviter les problèmes d'encodage
  127.     if ($newWidth % 2 -ne 0) { $newWidth-- }
  128.     if ($newHeight % 2 -ne 0) { $newHeight-- }
  129.    
  130.     $dir = Split-Path $file -Parent
  131.     $base = [System.IO.Path]::GetFileNameWithoutExtension($file)
  132.     $outFile = Join-Path $dir "$base`_resize.mp4"
  133.    
  134.     if ($OverwriteCheckbox.IsChecked) {
  135.         $outFile = Join-Path $dir "$base.mp4"
  136.         if (Test-Path $outFile) {
  137.             $result = [System.Windows.MessageBox]::Show("Le fichier existe déjà. Écraser ?", "Confirmation", "YesNo")
  138.             if ($result -ne "Yes") { return }
  139.         }
  140.     }
  141.    
  142.     Add-LogLine "Conversion de : $file"
  143.     Add-LogLine "Dimensions : $width x $height -> $newWidth x $newHeight"
  144.     Add-LogLine "Sortie : $outFile"
  145.     Add-LogLine "=== Démarrage de ffmpeg... ==="
  146.    
  147.     # Désactiver le bouton pendant la conversion
  148.     $ConvertButton.IsEnabled = $false
  149.    
  150.     # Lancer ffmpeg
  151.     $psi2 = New-Object System.Diagnostics.ProcessStartInfo
  152.     $psi2.FileName = $ffmpegCmd
  153.     $psi2.Arguments = "-i `"$file`" -vf `"scale=${newWidth}:${newHeight}:force_original_aspect_ratio=decrease`" -c:v libx264 -preset slow -crf 23 -c:a aac -b:a 192k -movflags +faststart -y `"$outFile`""
  154.     $psi2.UseShellExecute = $false
  155.     $psi2.RedirectStandardOutput = $true
  156.     $psi2.RedirectStandardError = $true
  157.     $psi2.CreateNoWindow = $true
  158.    
  159.     $process2 = New-Object System.Diagnostics.Process
  160.     $process2.StartInfo = $psi2
  161.    
  162.     # Utiliser un runspace pour exécuter en arrière-plan sans bloquer l'UI
  163.     $rs = [runspacefactory]::CreateRunspace()
  164.     $rs.Open()
  165.     $rs.SessionStateProxy.SetVariable("process2", $process2)
  166.     $rs.SessionStateProxy.SetVariable("OutputLog", $OutputLog)
  167.     $rs.SessionStateProxy.SetVariable("ConvertButton", $ConvertButton)
  168.     $rs.SessionStateProxy.SetVariable("window", $window)
  169.    
  170.     $ps = [powershell]::Create()
  171.     $ps.Runspace = $rs
  172.    
  173.     $ps.AddScript({
  174.         $process2.Start() | Out-Null
  175.        
  176.         while (-not $process2.StandardError.EndOfStream) {
  177.             $line = $process2.StandardError.ReadLine()
  178.             if ($line) {
  179.                 $window.Dispatcher.Invoke([action]{
  180.                     $OutputLog.AppendText("$line`r`n")
  181.                     $OutputLog.ScrollToEnd()
  182.                 })
  183.             }
  184.         }
  185.        
  186.         $process2.WaitForExit()
  187.        
  188.         $window.Dispatcher.Invoke([action]{
  189.             $OutputLog.AppendText("`r`n=== Conversion terminée ===`r`n")
  190.             $OutputLog.ScrollToEnd()
  191.             $ConvertButton.IsEnabled = $true
  192.         })
  193.     }) | Out-Null
  194.    
  195.     $ps.BeginInvoke() | Out-Null
  196. })
  197.  
  198. # Afficher la fenêtre
  199. $window.ShowDialog() | Out-Null
Advertisement
Add Comment
Please, Sign In to add comment