1111# Stop the script if an error occurs.
1212$ErrorActionPreference = ' Stop'
1313
14- $ScriptVersion = " 2.3 .0"
14+ $ScriptVersion = " 2.4 .0"
1515
1616<# *==========================================================================
1717* ℹ PARAMETERS
@@ -55,18 +55,19 @@ catch {
5555}
5656
5757$Defaults = @ {
58- DownloadFolderName = " yt-dlp"
59- UI_Path = " "
60- UseBrowserCookies = $true
61- browserCookies = " firefox"
62- myCookies = " "
63- templateNameChannel = " %(uploader)s - %(title)s.%(ext)s"
64- templateNameTitle = " %(title)s.%(ext)s"
65- useTitle = $true
66- videoQuality = " best"
67- videoContainer = " mp4"
68- autoAudio = @ (" https://music.youtube.com/watch?v=" )
69- jsRuntime = " bun"
58+ autoAudio = @ (" https://music.youtube.com/watch?v=" )
59+ browserCookies = " firefox"
60+ DownloadFolderName = " yt-dlp"
61+ jsRuntime = " bun"
62+ myCookies = " "
63+ SelectDownloadedFile = $true
64+ templateNameChannel = " %(uploader)s - %(title)s.%(ext)s"
65+ templateNameTitle = " %(title)s.%(ext)s"
66+ UI_Path = " "
67+ UseBrowserCookies = $true
68+ useTitle = $true
69+ videoContainer = " mp4"
70+ videoQuality = " best"
7071}
7172
7273foreach ($VarName in $Defaults.Keys ) {
@@ -93,6 +94,7 @@ New-Variable -Name protocol -Value "ytdl"
9394
9495New-Variable - Name repo - Value " https://github.com/Fred-Vatin/run-yt-dlp-from-browser" - Option Constant
9596
97+ New-Variable - Name IsTest - Value $false
9698
9799<# *==========================================================================
98100* ℹ FUNCTIONS
@@ -189,10 +191,13 @@ function TerminateWithError {
189191function WriteTitle {
190192 param (
191193 [Parameter (Mandatory = $true )]
192- [string ]$title
194+ [string ]$Title ,
195+
196+ [Parameter (Mandatory = $false )]
197+ [System.ConsoleColor ]$ForegroundColor = [System.ConsoleColor ]::Cyan
193198 )
194199
195- Write-Host " `n ===== $title =====`n " - ForegroundColor Cyan
200+ Write-Host " `n ===== $Title =====`n " - ForegroundColor $ForegroundColor
196201}
197202
198203# Check if the script is running with administrative privileges
@@ -231,6 +236,44 @@ function Test-FFmpegInstallation {
231236 TerminateWithError - errorMessage " FFmpeg is not installed globally on the system. Install it or add it to the PATH. You may need to restart the browser from where you call the command."
232237 }
233238}
239+
240+ # Colorize yt-dlp output
241+ function Out-ColoredLog {
242+ [CmdletBinding ()]
243+ param (
244+ [Parameter (ValueFromPipeline = $true )]
245+ [string ]$InputObject
246+ )
247+
248+ process {
249+ if ($InputObject -match ' ^(\[(?<tag>.+?)\])(?<remainder>.*)$' ) {
250+ $tag = $Matches [' tag' ]
251+ $remainder = $Matches [' remainder' ]
252+
253+ if ($tag -eq ' debug' ) {
254+ Write-Host $InputObject - ForegroundColor DarkGray
255+ }
256+ elseif ($tag -eq ' info' ) {
257+ Write-Host $InputObject - ForegroundColor DarkCyan
258+ }
259+ else {
260+ $color = switch ($tag ) {
261+ ' download' { ' Green' }
262+ ' warning' { ' Yellow' }
263+ ' error' { ' Red' }
264+ ' youtube' { ' Cyan' }
265+ default { ' White' }
266+ }
267+
268+ Write-Host " [$tag ]" - ForegroundColor $color - NoNewline
269+ Write-Host $remainder
270+ }
271+ }
272+ else {
273+ Write-Host $InputObject
274+ }
275+ }
276+ }
234277<# *==========================================================================
235278* ℹ GET PARAMETERS
236279===========================================================================#>
@@ -425,7 +468,7 @@ if ($url -and -not $install -and -not $uninstall) {
425468 # When QUALITY is an empty string, download the best audio
426469 $global :options = @ (
427470 " --extract-audio" ,
428- " -o " , " $output " ,
471+ " --output " , " $output " ,
429472 $DL_URL
430473 )
431474 }
@@ -434,16 +477,16 @@ if ($url -and -not $install -and -not $uninstall) {
434477 " --extract-audio" ,
435478 " --audio-format" , " mp3" ,
436479 " --audio-quality" , " 0" ,
437- " -o " , " $output " ,
438- " -f " , " bestaudio[ext=mp3]/bestaudio/bestvideo*+bestaudio" ,
480+ " --output " , " $output " ,
481+ " --format " , " bestaudio[ext=mp3]/bestaudio/bestvideo*+bestaudio" ,
439482 $DL_URL
440483 )
441484 }
442485 else {
443486 $global :options = @ (
444487 " --extract-audio" ,
445- " -o " , " $output " ,
446- " -f " , " bestaudio*[ext=$QUALITY ]/bestaudio/bestvideo*+bestaudio" ,
488+ " --output " , " $output " ,
489+ " --format " , " bestaudio*[ext=$QUALITY ]/bestaudio/bestvideo*+bestaudio" ,
447490 $DL_URL
448491 )
449492 }
@@ -460,18 +503,23 @@ if ($url -and -not $install -and -not $uninstall) {
460503 }
461504 }
462505 $global :options = @ (
463- " -f " , $videoQuality ,
506+ " --format " , $videoQuality ,
464507 " --merge-output-format" , $videoContainer ,
465- " -o " , " $output " ,
508+ " --output " , " $output " ,
466509 $DL_URL
467510 )
468511 }
469512 " test" {
470513 Write-Host " - Mode : test" - ForegroundColor Green
514+ $IsTest = $true
471515
472516 $global :options = @ (
473517 " --skip-download" ,
474- " --get-title" ,
518+ " --print" , " " ,
519+ " --print" , " Title : %(title)s" ,
520+ " --print" , " Duration : %(duration_string)s" ,
521+ " --print" , " Uploader : %(uploader)s" ,
522+ " --print" , " Default Formats : %(format)s" ,
475523 " --list-formats" ,
476524 $DL_URL
477525 )
@@ -512,12 +560,6 @@ if ($url -and -not $install -and -not $uninstall) {
512560 ===========================================================================#>
513561 Write-Host " `n COMMAND:" - ForegroundColor Cyan
514562
515-
516- # To display the correct command so it can be copied by user and used elsewhere
517- # we need to quote the output directory
518- $pattern = ' -o\s+(.+?)\s+http'
519- $substitution = ' -o "$1" http'
520-
521563 if ($UseBrowserCookies ) {
522564 $options += @ (" --cookies-from-browser" , " $browserCookies " )
523565 }
@@ -529,43 +571,104 @@ if ($url -and -not $install -and -not $uninstall) {
529571 $options += @ (" --js-runtimes" , $jsRuntime )
530572 }
531573
532- $optionsString = $options -join ' '
574+ # If video title contains a dot as last character, delete it
575+ if (-not $IsTest ) {
576+ $options += @ (" --replace-in-metadata" , " title" , ' \.$' , " " )
577+ }
578+
579+ if ($SelectDownloadedFile -and -not $IsTest ) {
580+ $options += @ (" --exec" , ' pwsh -NoProfile -NonInteractive -Command "Start-Process explorer.exe -ArgumentList \"/select,`\"{}`\"\""' )
581+ }
582+
583+ if ($IsTest ) {
584+ # quote option value when it contains space
585+ $optionsString = ($global :options | ForEach-Object {
586+ if ($_ -like ' * *' -or $_ -eq ' ' ) {
587+ ' "' + $_ + ' "'
588+ }
589+ else {
590+ $_
591+ }
592+ }) -join ' '
593+ }
594+ else {
595+ $optionsString = ($options ) -join ' '
596+ }
597+
598+ # To display the correct command so it can be copied by user and used elsewhere
599+ # we need to quote the output directory
600+ $pattern = ' --output\s+(.+?)\s+http'
601+ $substitution = ' --output "$1" http'
602+
603+ $optionsString = $optionsString -replace $pattern , $substitution
604+
605+ # we need to quote format
606+ $pattern = ' --format\s+?(.+?)\s'
607+ $substitution = ' --format "$1" '
533608
534609 $optionsString = $optionsString -replace $pattern , $substitution
535610
611+ if ($UseBrowserCookies ) {
612+ # we need to quote --cookies-from-browser
613+ $pattern = ' --cookies-from-browser\s+?(.+?)\s'
614+ $substitution = ' --cookies-from-browser "$1" '
615+
616+ $optionsString = $optionsString -replace $pattern , $substitution
617+ }
618+
536619 if ($myCookies ) {
537620 $pattern = ' --cookies\s+(.+?\.txt)'
538621 $substitution = ' --cookies "$1"'
539622 $optionsString = $optionsString -replace $pattern , $substitution
540623 }
541624
625+ if (-not $IsTest ) {
626+ $pattern = ' --replace-in-metadata\s+?(.+?)\s+(.+?\$)\s?'
627+ $substitution = ' --replace-in-metadata "$1" "$2" ""'
628+ $optionsString = $optionsString -replace $pattern , $substitution
629+ }
630+
631+ if ($SelectDownloadedFile -and -not $IsTest ) {
632+ $pattern = ' --exec\s+(.+)'
633+ $substitution = ' --exec '' $1'' '
634+ $optionsString = $optionsString -replace $pattern , $substitution -replace ' ,\s+' , ' ,'
635+ }
636+
542637 if ($debug ) {
543638 Write-Host " `$ options: $options `n " - ForegroundColor Cyan
544639 Write-Host " `$ optionsString: $optionsString `n " - ForegroundColor Yellow
545640 }
546641
547642 Write-Host " yt-dlp $optionsString `n " - ForegroundColor Magenta
548643 Write-Host " running command…(wait)`n " - ForegroundColor DarkGray
549- & yt- dlp $options
644+
645+ if ($IsTest ) {
646+ & yt- dlp $options
647+ }
648+ else {
649+ & yt- dlp $options 2>&1 | Out-ColoredLog
650+ }
550651
551652
552653 <# *==========================================================================
553654 * ℹ OPEN DOWNLOAD DIR
554655 ===========================================================================#>
555- if ($TYPE -ne " test" ) {
556- Write-Host " `n OPEN OUTPUT DIRECTORY" - ForegroundColor Cyan
557- try {
558- # Open download dir in the default file explorer
559- Invoke-Item - Path $DL_DIR
560- }
561- catch {
562- TerminateWithError " Invoke-Item -Path $DL_DIR [failed]"
656+ if ($LASTEXITCODE -eq 0 ) {
657+
658+ if (-not $IsTest ) {
659+ Write-Host " `n OPEN OUTPUT DIRECTORY" - ForegroundColor Cyan
563660 }
564661
565662 # Play a beep to notify
566663 [console ]::beep(650 , 1000 )
664+
665+ WriteTitle " SCRIPT ENDED WITH NO ERROR"
666+
667+ }
668+ else {
669+ WriteTitle " SCRIPT ENDED WITH ERROR" - ForegroundColor Red
670+ TerminateWithError - errorMessage " yt-dlp terminate with error"
567671 }
568- WriteTitle " SCRIPT ENDED WITH NO ERROR"
569672
570673 # Read-Host -Prompt "Press Enter to exit"
571674
0 commit comments