Extension/YouTubeDL.RoughDraft.Extension.ps1

<#
.SYNOPSIS
    Youtube Downloader
.DESCRIPTION
    Extends Get-Media to enable the downloading of videos from YouTube and other sources, using YouTubeDL
.LINK
    http://ytdl-org.github.io/youtube-dl/
#>

[Management.Automation.Cmdlet("Get","Media")]
[ComponentModel.Inheritance("NotInherited")] # that is not inherited (this is the default).
param(
[Parameter(Mandatory)]
[Alias('YouTubeURI')]
[uri]
$YouTubeURL,

# The YouTubeDL Output File. See [documentation](https://github.com/ytdl-org/youtube-dl/blob/master/README.md#output-template)
[Alias('YouTubeOutputFormat')]
[string]
$YouTubeOutputFile,

# If set, will force a download of the latest YouTubeDL (even if one is already found). It will be placed in $home/.RoughDraft/.
[switch]
$DownloadLatestYouTubeDL,

# If set, will download auto-generated subtitles.
[switch]
$AutoGeneratedSubtitle,

# If set, will download all subtitles.
[switch]
$AllSubtitle,

[Alias('YouTubeDLArgs','YouTubeDLArg')]
[string[]]
$YouTubeDownloadArgumentList,

# If set, will return the information about the download, instead of downloading.
[Alias('YouTubeDLInfo', 'YouTubeInfo')]
[switch]
$YouTubeDownloadInformation
)

$roughDraftRoot = Join-Path $home ".RoughDraft"
if (-not (Test-Path -Path $roughDraftRoot)) {
    $null = New-Item -ItemType Directory -Path $roughDraftRoot
}

$YouTubeDLName =
    if ($PSVersionTable.PlatForm -like 'Win*' -or -not $PSVersionTable.Platform) {
        "youtube-dl.exe"
    } else {
        "youtube-dl"
    }
$YouTubeDLPath = Join-Path $roughDraftRoot $YouTubeDLName

if ($DownloadLatestYouTubeDL -or -not (Test-Path $YouTubeDLPath)) {
    $latestRelease = Invoke-RestMethod -Uri https://api.github.com/repos/ytdl-org/youtube-dl/releases?per_page=1
    $assetUrl = $latestRelease.Assets | Where-Object Name -eq $YouTubeDLName | Select-Object -ExpandProperty Browser_Download_Url
    [Net.WebClient]::new().DownloadFile($assetUrl, "$YouTubeDLPath")
}

$AllYouTubeDLArgs  = @(
    if ($AutoGeneratedSubtitle) {
        "--write-auto-sub"
    }
    if ($AllSubtitle) {
        "--all-subs"        
    }
    if ($YouTubeDownloadInformation) {
        '--json'
    }
    if ($YouTubeOutputFile) {
        '-o'
        $YouTubeOutputFile
    }
)

if ($YouTubeDownloadArgumentList -like '--json' -or $YouTubeDownloadInformation) {
    @(& $YouTubeDLPath $YouTubeURL @AllYouTubeDLArgs) -join [Environment]::NewLine | ConvertFrom-Json
}
elseif ($YouTubeDownloadArgumentList) {
    @(& $YouTubeDLPath $YouTubeURL @AllYouTubeDLArgs)
}
else {
    $YouTubeDestinations = @()
    $progId = Get-Random
    & $YouTubeDLPath $YouTubeURL @AllYouTubeDLArgs *>&1 |
        ForEach-Object {
            
            $outLine  = "$_"
            Write-Verbose "$outline"
            if ($outline -like 'ERROR:*') {
                Write-Error ($outline -replace '^ERROR:')
                return
            }
            if ($outLine-match '^\[download\]\s+(?<p>[\d\.]+)+%') {
                Write-Progress "Downloading" " $youTubeURL" -PercentComplete $matches.p -Id $progId
            } elseif ($outLine -match '^\[download\] Destination:') {
                $YouTubeDestinations += $outLine -replace '^\[download\] Destination:\s+'
            }

            if ($outline -match 'has already been downloaded\s{0,}$') {
                $YouTubeDestinations += $outline -replace 'has already been downloaded\s{0,}$' -replace '^\[download\]\s+'
            }
            
        } -End {
            Write-Progress "Downloading" " $youTubeURL" -Completed -Id $progId
        }

    foreach ($YouTubeDestination in $YouTubeDestinations) {
        if (Test-Path $YouTubeDestination) {
            Get-Item $YouTubeDestination
        }
    }    
}