Skip to content

Instantly share code, notes, and snippets.

@disco0
Created November 18, 2020 10:01
Show Gist options
  • Save disco0/e3b1a073dca51294414967fe410b9d48 to your computer and use it in GitHub Desktop.
Save disco0/e3b1a073dca51294414967fe410b9d48 to your computer and use it in GitHub Desktop.
mpv-player-windows Build Updater
#Requires -PSEdition Desktop
#Requires -Module 7Zip4Powershell
<#
.SYNOPSIS
Download and install the latest available mpv Windows build
.DESCRIPTION
Script can either be invoked directly for an immeditate update with default
configuration or sourced to access the component functions. Currently only 64 bit builds
are enumerated, but the urls can be easily switched in `Get-Latestx64mpvWinBuildUrl`
Defaults
Install Directory:
PATH is checked for mpv command, and its directory will be updated. If not
found, $global:MpvInstallDirectory will be checked and used as for a directory path
string if found. If all methods fail the script or install function will abort.
Build Archives:
Archives are downloaded to $ENV:TMP, and can also be configured.
This was tested once and immediately worked for me, so good luck!
.NOTES
Powershell 5.1 is required for the HTML parsing methods not available in Core editions.
I don't imagine this being an issue considering its a Windows build installer, but if
needed one could use AngleParse for loading links.
#>
using namespace System.IO
using namespace System.Management.Automation
#region Splat
$Silent =
@{
ErrorAction = [ActionPreference]::SilentlyContinue
}
#endregion Splat
#region Env
function Find-ExistingMpvInstallDirectory()
{
[cmdletbinding()]
[OutputType([DirectoryInfo])]
param(
[string] $MpvCommandName = "mpv"
)
Get-Command $MpvCommandName @Silent -CommandType Application `
| Select-Object -First 1 -ExpandProperty Source | Get-Item @Silent `
| Select-Object -ExpandProperty Directory | Get-Item @Silent `
| ForEach-Object {
if($_)
{
Write-Verbose "Resolved existing mpv install directory: ${_}"
}
$_
}
}
$InstallDir = Find-ExistingMpvInstallDirectory
if(!($InstallDir) -and ($null -ne $global:MpvInstallDirectory))
{
$InstallDir = Get-Item $global:MpvInstallDirectory
}
#endregion Env
#region Util
function Extract-UrlFilename()
{
[cmdletbinding()] [OutputType([String])]
param(
[Parameter(Mandatory = $true)]
[ValidatePattern('\w+?:.*')]
[string] $Url
)
($Url -split "/")[-1] -replace '(?<=\.\w+)\?.*', ''
}
# From before I realized 5.1 was necessary
$JoinPath = if(!([Path]::Join)){ [Path]::Combine } else { [Path]::Join }
#endregion Util
#region Get Release Url
function Get-Latestx64mpvWinBuildUrl()
{
[OutputType([String])]
#region x64 Releases Page
$x64ReleasesUrl = "https://sourceforge.net/projects/mpv-player-windows/files/64bit/"
$x64ReleasesPage = (Invoke-WebRequest $x64ReleasesUrl)
$latestEl = $x64ReleasesPage.parsedHtml.querySelector("tbody > tr > th > a")
$latestUrl = $latestEl.href
if(!$latestUrl)
{
Write-Error "Failed to get latest release url."
return
}
Write-Host -n -F Cyan "Latest release's download url: "
Write-Host -F Green "${latestUrl}";
#endregion x64 Releases Page
#region Download Page
$downloadPage = (Invoke-WebRequest $latestUrl)
$downloadEl = $downloadPage.parsedHtml.querySelector("#btn-problems-downloading")
$downloadUrl = $downloadEl.getAttribute("data-release-url")
if(!$downloadUrl)
{
Write-Error "Failed to get download url."
return
}
Write-Host -n -F Cyan "Release download url: "
Write-Host -F Green "${downloadUrl}";
#endregion Download Page
$downloadUrl
}
#endregion Get Release Url
#region Download Release
function Download-LatestmpvRelease()
{
[cmdletbinding()]
[OutputType([FileInfo])]
param(
[Parameter(Position = 0)]
[ValidateScript({$_ -ne "" -and [Directory]::Exists($_)})]
# DownloadPath: DirectoryInfo | string
$DownloadPath = (Get-Item "${ENV:TMP}"),
[string]
[ValidatePattern('https?:.*')]
[Parameter()]
$Url = (Get-Latestx64mpvWinBuildUrl),
[Switch] $HideProgress
)
if(!$url)
{
Write-Error "Failed to get build download url."
return
}
if(![Directory]::Exists($DownloadPath.FullName))
{
Write-Error -Message "Directory does not exist: ${DownloadPath}"
return
}
$outFileName = Extract-UrlFilename $Url;
$outFilePath = $JoinPath.invoke($DownloadPath , $outFileName);
if(!(Test-Path -IsValid $outFileName))
{
Write-Error "Generated download path is invalid: ${outFilePath}"
return
}
if($HideProgress)
{
$ProgressPreferenceInitial = $ProgressPreference
$ProgressPreference = [ActionPreference]::SilentlyContinue;
try
{
Invoke-WebRequest $Url -OutFile $outFilePath
}
catch
{
}
finally
{
$ProgressPreference = $ProgressPreferenceInitial
}
}
else
{
Invoke-WebRequest $Url -OutFile $outFilePath
}
Write-Host -F Cyan "Downloaded release to ${outFilePath}."
if(!([File]::Exists($outFilePath)))
{
Write-Error "No File found at download path: ${outFilePath}"
return
}
Get-Item $outFilePath
}
#endregion Download Release
#region Install Release
function Install-mpvReleaseArchive()
{
[cmdletbinding()]
[OutputType([FileInfo])]
param(
[FileInfo] $Archive,
[DirectoryInfo] $InstallDirectory
)
if(!([File]::Exists($Archive)))
{
Write-Error "Archive file does not exist: ${Archive}"
return
}
if(!(Test-Path -IsValid $InstallDirectory))
{
Write-Error "Invalid install directory: ${InstallDirectory}"
return
}
# Extract archive directly into install path for now
Write-Host -N "Installing mpv archive to directory: "
Write-Host -N -F Cyan $InstallDirectory
Expand-7Zip -ArchiveFileName $Archive.FullName -TargetPath $InstallDirectory.FullName
}
#endregion Install Release
#region Update Release
function Update-mpvWindowsBuild()
{
[cmdletbinding()]
param(
[Parameter(Position = 0)]
[ValidateScript({$_ -ne "" -and [Directory]::Exists($_)})]
# InstallDirectory: DirectoryInfo | string
$InstallDirectory = $InstallDir,
[Parameter(Position = 1)]
[ValidateScript({$_ -ne "" -and [Directory]::Exists($_)})]
# DownloadPath: DirectoryInfo | string
$DownloadPath = (Get-Item "${ENV:TMP}")
)
$archive = Download-LatestmpvRelease -DownloadPath $DownloadPath
if($archive)
{
Install-mpvReleaseArchive -Archive $archive -InstallDirectory $InstallDirectory
}
}
#endregion Update Release
# Execute immediately if not being sourced
if($MyInvocation.InvocationName -notmatch '^\.$')
{
Update-mpvWindowsBuild
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment