Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Windows.Forms
# Déterminer le dossier du script et localiser ffmpeg/ffprobe
try {
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
} catch {
$scriptDir = Get-Location
}
$ffmpegCmd = Join-Path $scriptDir "ffmpeg.exe"
$ffprobeCmd = Join-Path $scriptDir "ffprobe.exe"
# Vérifier la présence de ffmpeg/ffprobe
if (-not (Test-Path $ffmpegCmd)) {
[System.Windows.MessageBox]::Show("ffmpeg.exe est introuvable dans le dossier du script.")
exit
}
if (-not (Test-Path $ffprobeCmd)) {
[System.Windows.MessageBox]::Show("ffprobe.exe est introuvable dans le dossier du script.")
exit
}
# Créer la fenêtre WPF
[xml]$xaml = @"
Title="Convertisseur vidéo (H.264 + AAC)" Height="500" Width="650"
WindowStartupLocation="CenterScreen" ResizeMode="NoResize" Background="#202020">
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Fichier vidéo :" Foreground="White" Margin="0,0,0,5"/>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBox x:Name="InputFile" Width="450" Margin="0,0,5,0"/>
<Button x:Name="BrowseButton" Content="Parcourir..." Width="120"/>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Redimensionnement (%) :" Foreground="White" VerticalAlignment="Center"/>
<TextBox x:Name="ResizePercent" Width="60" Margin="10,0,0,0" Text="100"/>
</StackPanel>
<StackPanel Grid.Row="3" Orientation="Horizontal" Margin="0,10,0,0">
<CheckBox x:Name="OverwriteCheckbox" Content="Écraser le fichier existant" Foreground="White"/>
</StackPanel>
<TextBox x:Name="OutputLog" Grid.Row="4" Margin="0,10,0,10" AcceptsReturn="True"
VerticalScrollBarVisibility="Auto" Background="#101010" Foreground="#00FF00" FontFamily="Consolas"/>
<Button x:Name="ConvertButton" Grid.Row="5" Content="Convertir" Width="120" Height="30"
HorizontalAlignment="Right" Margin="0,10,0,0"/>
</Grid>
</Window>
"@
# Charger le XAML
$reader = New-Object System.Xml.XmlNodeReader $xaml
$window = [Windows.Markup.XamlReader]::Load($reader)
# Associer les contrôles
$BrowseButton = $window.FindName("BrowseButton")
$InputFile = $window.FindName("InputFile")
$ResizePercent = $window.FindName("ResizePercent")
$OutputLog = $window.FindName("OutputLog")
$ConvertButton = $window.FindName("ConvertButton")
$OverwriteCheckbox = $window.FindName("OverwriteCheckbox")
# Fonction pour journaliser dans la zone de texte
function Add-LogLine {
param($text)
$OutputLog.AppendText("$text`r`n")
$OutputLog.ScrollToEnd()
}
# Parcourir un fichier
$BrowseButton.Add_Click({
$ofd = New-Object System.Windows.Forms.OpenFileDialog
$ofd.Filter = "Fichiers vidéo|*.mp4;*.mkv;*.avi;*.mov;*.flv;*.wmv;*.webm|Tous les fichiers|*.*"
if ($ofd.ShowDialog() -eq "OK") {
$InputFile.Text = $ofd.FileName
}
})
# Conversion
$ConvertButton.Add_Click({
$file = $InputFile.Text
if (-not (Test-Path $file)) {
[System.Windows.MessageBox]::Show("Veuillez sélectionner un fichier vidéo valide.")
return
}
$percent = [int]$ResizePercent.Text
if ($percent -le 0) { $percent = 100 }
Add-LogLine "Lecture des dimensions de la vidéo..."
# Lire les dimensions avec ffprobe
$psi = New-Object System.Diagnostics.ProcessStartInfo
$psi.FileName = $ffprobeCmd
$psi.Arguments = "-v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 `"$file`""
$psi.UseShellExecute = $false
$psi.RedirectStandardOutput = $true
$psi.RedirectStandardError = $true
$psi.CreateNoWindow = $true
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $psi
$process.Start() | Out-Null
$dimensions = $process.StandardOutput.ReadToEnd().Trim()
$process.WaitForExit()
if (-not $dimensions -or $dimensions -eq "") {
Add-LogLine "Erreur : impossible de lire les dimensions."
return
}
$dims = $dimensions -split ","
$width = [int]$dims[0]
$height = [int]$dims[1]
$newWidth = [int]($width * $percent / 100)
$newHeight = [int]($height * $percent / 100)
# Arrondir à un nombre pair pour éviter les problèmes d'encodage
if ($newWidth % 2 -ne 0) { $newWidth-- }
if ($newHeight % 2 -ne 0) { $newHeight-- }
$dir = Split-Path $file -Parent
$base = [System.IO.Path]::GetFileNameWithoutExtension($file)
$outFile = Join-Path $dir "$base`_resize.mp4"
if ($OverwriteCheckbox.IsChecked) {
$outFile = Join-Path $dir "$base.mp4"
if (Test-Path $outFile) {
$result = [System.Windows.MessageBox]::Show("Le fichier existe déjà. Écraser ?", "Confirmation", "YesNo")
if ($result -ne "Yes") { return }
}
}
Add-LogLine "Conversion de : $file"
Add-LogLine "Dimensions : $width x $height -> $newWidth x $newHeight"
Add-LogLine "Sortie : $outFile"
Add-LogLine "=== Démarrage de ffmpeg... ==="
# Désactiver le bouton pendant la conversion
$ConvertButton.IsEnabled = $false
# Lancer ffmpeg
$psi2 = New-Object System.Diagnostics.ProcessStartInfo
$psi2.FileName = $ffmpegCmd
$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`""
$psi2.UseShellExecute = $false
$psi2.RedirectStandardOutput = $true
$psi2.RedirectStandardError = $true
$psi2.CreateNoWindow = $true
$process2 = New-Object System.Diagnostics.Process
$process2.StartInfo = $psi2
# Utiliser un runspace pour exécuter en arrière-plan sans bloquer l'UI
$rs = [runspacefactory]::CreateRunspace()
$rs.Open()
$rs.SessionStateProxy.SetVariable("process2", $process2)
$rs.SessionStateProxy.SetVariable("OutputLog", $OutputLog)
$rs.SessionStateProxy.SetVariable("ConvertButton", $ConvertButton)
$rs.SessionStateProxy.SetVariable("window", $window)
$ps = [powershell]::Create()
$ps.Runspace = $rs
$ps.AddScript({
$process2.Start() | Out-Null
while (-not $process2.StandardError.EndOfStream) {
$line = $process2.StandardError.ReadLine()
if ($line) {
$window.Dispatcher.Invoke([action]{
$OutputLog.AppendText("$line`r`n")
$OutputLog.ScrollToEnd()
})
}
}
$process2.WaitForExit()
$window.Dispatcher.Invoke([action]{
$OutputLog.AppendText("`r`n=== Conversion terminée ===`r`n")
$OutputLog.ScrollToEnd()
$ConvertButton.IsEnabled = $true
})
}) | Out-Null
$ps.BeginInvoke() | Out-Null
})
# Afficher la fenêtre
$window.ShowDialog() | Out-Null