automated mpv installation in windows & Player bug of playlist/track caching fixed

This commit is contained in:
KRTirtho 2021-05-04 18:07:38 -07:00
parent b117e93025
commit 7d810417cd
5 changed files with 392 additions and 9266 deletions

View File

@ -6,19 +6,44 @@ if(Test-Path "$ScriptDir\qode.exe"){
$WannaRemove = Read-Host -Prompt "Are you sure to uninstall?[y]Yes/[n]No"
$WannaRemove = $WannaRemove.Trim().ToLower()
if($WannaRemove -eq "y"){
echo "Removing all the contents"
Write-Output "Removing all the contents"
Get-ChildItem $ScriptDir -Recurse | Remove-Item
# now deleting mpv player
$DeleteMpv = Read-Host -Prompt "Do you want to delete mpv player?[y]Yes/[n]No"
if ($DeleteMpv -eq "y") {
$Mpv_Dir = "$Env:ProgramData\Spotube"
Write-Output "Deleting Mpv player"
Remove-Item -Path $Mpv_Dir -Recurse
Write-Output "Deleted Mpv player"
Write-Output "Removing environment variables"
# Get it
$pathMachine = [System.Environment]::GetEnvironmentVariable('PATH','Machine')
$pathUser = [System.Environment]::GetEnvironmentVariable('PATH','User')
# Remove unwanted elements
$pathMachine = ($pathMachine.Split(';') | Where-Object { $_ -ne "$Mpv_Dir\mpv" }) -join ';'
$pathUser = ($pathUser.Split(';') | Where-Object { $_ -ne "$Mpv_Dir\mpv" }) -join ';'
# Set it
[System.Environment]::SetEnvironmentVariable('PATH', $pathMachine, 'Machine')
[System.Environment]::SetEnvironmentVariable('PATH', $pathUser, 'User')
}
elseif($DeleteMpv -eq "n") {
Write-Output "Ok, keeping mpv player"
}
else{
throw "Wrong Option, use either 'y' or 'n', aborting..."
}
$DeleteData = Read-Host -Prompt "Do you want to delete all data & caches?[y]Yes/[n]No"
$DeleteData = $DeleteData.Trim().ToLower()
if ($DeleteData -eq "y") {
echo "Deleting data & caches"
Write-Output "Deleting data & caches"
Remove-Item -Path "$Home\.config\spotube" -Recurse
Remove-Item -Path "$Home\.cache\spotube" -Recurse
echo "Deleted caches & data"
Write-Output "Deleted caches & data"
}
elseif($DeleteData -eq "n") {
echo "Ok, keeping those"
Write-Output "Ok, keeping those"
}
else{
throw "Wrong Option, use either 'y' or 'n', aborting..."
@ -31,17 +56,17 @@ if(Test-Path "$ScriptDir\qode.exe"){
foreach($shortcut in $shortcut_paths){
if(Test-Path $shortcut){
echo "Deleting Shortcut: $shortcut"
Write-Output "Deleting Shortcut: $shortcut"
Remove-Item -Path $shortcut
}
}
echo "Uninstall complete, just delete the Spotube folder now"
echo "Will miss you💕!"
Write-Output "Uninstall complete, just delete the Spotube folder now"
Write-Output "Will miss you💕!"
}
elseif($WannaRemove -eq "n"){
echo "Thank god you didn't, quitting..."
Write-Output "Thank god you didn't, quitting..."
}
else{
throw "Wrong Option, use either 'y' or 'n', aborting..."

View File

@ -0,0 +1,299 @@
param (
[String]$CWD = (Get-Location).Path
)
echo "Script Location: " + (Get-Location).Path
echo "Install PATH: $CWD"
Set-Location -Path $CWD
echo "Script new Location: " + (Get-Location).Path
function Check-7z {
$7zdir = $CWD + "\7z"
if (-not (Test-Path ($7zdir + "\7za.exe")))
{
$download_file = $CWD + "\7z.zip"
Write-Host "Downloading 7z" -ForegroundColor Green
Invoke-WebRequest -Uri "https://download.sourceforge.net/sevenzip/7za920.zip" -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::FireFox -OutFile $download_file
Write-Host "Extracting 7z" -ForegroundColor Green
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($download_file, $7zdir)
Remove-Item -Force $download_file
}
else
{
Write-Host "7z already exist. Skipped download" -ForegroundColor Green
}
}
function Check-PowershellVersion {
$version = $PSVersionTable.PSVersion.Major
Write-Host "Checking Windows PowerShell version -- $version" -ForegroundColor Green
if ($version -le 2)
{
Write-Host "Using Windows PowerShell $version is unsupported. Upgrade your Windows PowerShell." -ForegroundColor Red
throw
}
}
function Check-Youtubedl {
$youtubedl = $CWD + "\youtube-dl.exe"
$is_exist = Test-Path $youtubedl
return $is_exist
}
function Check-Mpv {
$mpv = $CWD + "\mpv.exe"
$is_exist = Test-Path $mpv
return $is_exist
}
function Download-Mpv ($filename) {
echo "MPV Filename: $filename"
Write-Host "Downloading" $filename -ForegroundColor Green
$global:progressPreference = 'Continue'
$link = "https://download.sourceforge.net/mpv-player-windows/" + $filename
Invoke-WebRequest -Uri $link -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::FireFox -OutFile $filename
}
function Download-Youtubedl ($version) {
Write-Host "Downloading youtube-dl ($version)" -ForegroundColor Green
$global:progressPreference = 'Continue'
$link = "https://yt-dl.org/downloads/" + $version + "/youtube-dl.exe"
Invoke-WebRequest -Uri $link -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::FireFox -OutFile "youtube-dl.exe"
}
function Extract-Mpv ($file) {
$7za = $CWD + "\7z\7za.exe"
Write-Host "Extracting" $file -ForegroundColor Green
echo "MPV Extract Path: $file"
& $7za x -y $file
}
function Get-Latest-Mpv($Arch) {
$i686_link = "https://sourceforge.net/projects/mpv-player-windows/rss?path=/32bit"
$x86_64_link = "https://sourceforge.net/projects/mpv-player-windows/rss?path=/64bit"
$link = ''
switch ($Arch)
{
i686 { $link = $i686_link}
x86_64 { $link = $x86_64_link }
}
Write-Host "Fetching RSS feed for mpv" -ForegroundColor Green
$result = [xml](New-Object System.Net.WebClient).DownloadString($link)
$latest = $result.rss.channel.item.link[0]
$filename = $latest.split("/")[-2]
return [System.Uri]::UnescapeDataString($filename)
}
function Get-Latest-Youtubedl {
$link = "https://yt-dl.org/downloads/latest/youtube-dl.exe"
Write-Host "Fetching RSS feed for youtube-dl" -ForegroundColor Green
$global:progressPreference = 'silentlyContinue'
$resp = Invoke-WebRequest $link -MaximumRedirection 0 -ErrorAction Ignore -UseBasicParsing
$redirect_link = $resp.Headers.Location
$version = $redirect_link.split("/")[4]
return $version
}
function Get-Arch {
# Reference: http://superuser.com/a/891443
$FilePath = [System.IO.Path]::Combine($CWD, 'mpv.exe')
[int32]$MACHINE_OFFSET = 4
[int32]$PE_POINTER_OFFSET = 60
[byte[]]$data = New-Object -TypeName System.Byte[] -ArgumentList 4096
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList ($FilePath, 'Open', 'Read')
$stream.Read($data, 0, 4096) | Out-Null
# DOS header is 64 bytes, last element, long (4 bytes) is the address of the PE header
[int32]$PE_HEADER_ADDR = [System.BitConverter]::ToInt32($data, $PE_POINTER_OFFSET)
[int32]$machineUint = [System.BitConverter]::ToUInt16($data, $PE_HEADER_ADDR + $MACHINE_OFFSET)
$result = "" | select FilePath, FileType
$result.FilePath = $FilePath
switch ($machineUint)
{
0 { $result.FileType = 'Native' }
0x014c { $result.FileType = 'i686' } # 32bit
0x0200 { $result.FileType = 'Itanium' }
0x8664 { $result.FileType = 'x86_64' } # 64bit
}
$result
}
function ExtractGitFromFile {
$stripped = .\mpv --no-config | select-string "mpv" | select-object -First 1
$pattern = "-g([a-z0-9-]{7})"
$bool = $stripped -match $pattern
return $matches[1]
}
function ExtractGitFromURL($filename) {
$pattern = "-git-([a-z0-9-]{7})"
$bool = $filename -match $pattern
return $matches[1]
}
function ExtractDateFromFile {
$date = (Get-Item ./mpv.exe).LastWriteTimeUtc
$day = $date.Day.ToString("00")
$month = $date.Month.ToString("00")
$year = $date.Year.ToString("0000")
return "$year$month$day"
}
function ExtractDateFromURL($filename) {
$pattern = "mpv-[xi864_]*-([0-9]{8})-git-([a-z0-9-]{7})"
$bool = $filename -match $pattern
return $matches[1]
}
function Test-Admin
{
$user = [Security.Principal.WindowsIdentity]::GetCurrent();
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
function Upgrade-Mpv {
$need_download = $false
$remoteName = ""
$arch = ""
if (Check-Mpv) {
$arch = (Get-Arch).FileType
$remoteName = Get-Latest-Mpv $arch
$localgit = ExtractGitFromFile
$localdate = ExtractDateFromFile
$remotegit = ExtractGitFromURL $remoteName
$remotedate = ExtractDateFromURL $remoteName
if ($localgit -match $remotegit)
{
if ($localdate -match $remotedate)
{
Write-Host "You are already using latest mpv build -- $remoteName" -ForegroundColor Green
$need_download = $false
}
else {
Write-Host "Newer mpv build available" -ForegroundColor Green
$need_download = $true
}
}
else {
Write-Host "Newer mpv build available" -ForegroundColor Green
$need_download = $true
}
}
else {
Write-Host "mpv doesn't exist. " -ForegroundColor Green -NoNewline
$result = Read-KeyOrTimeout "Proceed with downloading? [Y/n] (default=y)" "Y"
Write-Host ""
if ($result -eq "Y") {
$need_download = $true
if (Test-Path (Join-Path $env:windir "SysWow64")) {
Write-Host "Detecting System Type is 64-bit" -ForegroundColor Green
$arch = "x86_64"
}
else {
Write-Host "Detecting System Type is 32-bit" -ForegroundColor Green
$arch = "i686"
}
$remoteName = Get-Latest-Mpv $arch
}
else {
$need_download = $false
}
}
if ($need_download) {
Download-Mpv $remoteName
Check-7z
Extract-Mpv $remoteName
}
}
function Upgrade-Youtubedl {
$need_download = $false
$latest_release = Get-Latest-Youtubedl
if (Check-Youtubedl) {
if ((.\youtube-dl --version) -match ($latest_release)) {
Write-Host "You are already using latest youtube-dl -- $latest_release" -ForegroundColor Green
$need_download = $false
}
else {
Write-Host "Newer youtube-dl build available" -ForegroundColor Green
$need_download = $true
}
}
else {
Write-Host "youtube-dl doesn't exist. " -ForegroundColor Green -NoNewline
$result = Read-KeyOrTimeout "Proceed with downloading? [Y/n] (default=y)" "Y"
Write-Host ""
if ($result -eq 'Y') {
$need_download = $true
}
else {
$need_download = $false
}
}
if ($need_download) {
Download-Youtubedl $latest_release
}
}
function Read-KeyOrTimeout ($prompt, $key){
$seconds = 20
$startTime = Get-Date
$timeOut = New-TimeSpan -Seconds $seconds
Write-Host "$prompt " -ForegroundColor Green
# Basic progress bar
[Console]::CursorLeft = 0
[Console]::Write("[")
[Console]::CursorLeft = $seconds + 2
[Console]::Write("]")
[Console]::CursorLeft = 1
while (-not [System.Console]::KeyAvailable) {
$currentTime = Get-Date
Start-Sleep -s 1
Write-Host "#" -ForegroundColor Green -NoNewline
if ($currentTime -gt $startTime + $timeOut) {
Break
}
}
if ([System.Console]::KeyAvailable) {
$response = [System.Console]::ReadKey($true).Key
}
else {
$response = $key
}
return $response.ToString()
}
#
# Main script entry point
#
if (Test-Admin) {
Write-Host "Running script with administrator privileges" -ForegroundColor Yellow
}
else {
Write-Host "Running script without administrator privileges" -ForegroundColor Red
}
try {
Check-PowershellVersion
# Sourceforge only support TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Upgrade-Mpv
Upgrade-Youtubedl
Write-Host "Operation completed" -ForegroundColor Magenta
}
catch [System.Exception] {
Write-Host $_.Exception.Message -ForegroundColor Red
exit 1
}

View File

@ -12,9 +12,9 @@ function CreateShortcut([String]$InstallLocation) {
$Target = "$InstallLocation\qode.exe"
$WshShell = New-Object -comObject WScript.Shell
echo "Creating shortcuts"
Write-Output "Creating shortcuts"
foreach($shortcut in $shortcut_paths){
echo $shortcut
Write-Output $shortcut
$StartShortcut = $WshShell.CreateShortcut($shortcut)
$StartShortcut.TargetPath = $Target
$StartShortcut.WorkingDirectory = $InstallLocation
@ -36,21 +36,24 @@ function InstallSpotube {
if(!$Spotube_Location.Trim()){
New-Item -Path $Env:Programfiles -Name "Spotube" -ItemType "directory"
[System.IO.Compression.ZipFile]::ExtractToDirectory("$ScriptDir\spotube.data", $Spotube_Dir)
Install-Mpv -SpotubeLocation $Spotube_Dir
}
else{
New-Item -Path Spotube_Location -Name "Spotube" -ItemType "directory"
[System.IO.Compression.ZipFile]::ExtractToDirectory("$ScriptDir\spotube.data", "$Spotube_Location\Spotube")
$Spotube_Location = "$Spotube_Location\Spotube"
[System.IO.Compression.ZipFile]::ExtractToDirectory("$ScriptDir\spotube.data", $Spotube_Location)
Install-Mpv -SpotubeLocation $Spotube_Location
}
$WannaCreateShortcut = Read-Host -Prompt "Do you want to create shortcuts?[y]Yes/[n]No"
$WannaCreateShortcut = $WannaCreateShortcut.Trim().ToLower()
if($WannaCreateShortcut -eq "y"){
if(!$Spotube_Location.Trim()){
$Spotube_Location= $Env:Programfiles
$Spotube_Location= $Spotube_Dir
}
CreateShortcut -InstallLocation "$Spotube_Location\Spotube"
CreateShortcut -InstallLocation $Spotube_Location
}
elseif($WannaCreateShortcut -eq "n"){
echo "Ok, skipping this part"
Write-Output "Ok, skipping this part"
}
else{
throw "Wrong Option, use either 'y' or 'n', aborting..."
@ -58,22 +61,44 @@ function InstallSpotube {
}
function Install-Mpv{
param([String]$SpotubeLocation)
$Mpv_Dir = "$Env:ProgramData"
if(!(Test-Path "$Mpv_Dir\Spotube")){
New-Item -Path $Mpv_Dir -Name "Spotube" -ItemType "directory"
}
$Mpv_Dir = "$Env:ProgramData\Spotube"
if(!(Test-Path "$Mpv_Dir\mpv")){
New-Item -Path $Mpv_Dir -Name "mpv" -ItemType "directory"
}
$Mpv_Dir = "$Mpv_Dir\mpv"
# invoking the scripts for downloading mpv player
Write-Output "Downloading mpv player"
Invoke-Expression "& '$SpotubeLocation\deps\bootstrap-mpv.ps1' -CWD '$Mpv_Dir'"
# setting the env vars
if (!($ENV:Path.Contains($Mpv_Dir))) {
Write-Output "Setting environment vars"
[System.Environment]::SetEnvironmentVariable("Path", "$ENV:Path;$Mpv_Dir", [System.EnvironmentVariableTarget]::Machine)
[System.Environment]::SetEnvironmentVariable("Path", "$ENV:Path;$Mpv_Dir", [System.EnvironmentVariableTarget]::User)
}
}
if(!(Test-Path $Spotube_Dir)){
InstallSpotube -PromptLocation $True
}
# reinstallation procedure
else{
echo "Spotube already exists in $Env:Programfiles\Spotube"
Write-Output "Spotube already exists in $Env:Programfiles\Spotube"
$WannaReplace = Read-Host -Prompt "Do you want to reinstall?[y]Yes/[n]No"
$WannaReplace = $WannaReplace.Trim().ToLower()
if($WannaReplace -eq "y"){
echo "Removing Old Spotube"
Remove-Item -Path "$Spotube_Dir" -Recurse
echo "Installing New Spotube"
Write-Output "Removing Old Spotube"
Remove-Item -Path "$Spotube_Dir" -Recurse -Exclude "$Spotube_Dir\mpv"
Write-Output "Installing New Spotube"
InstallSpotube
}
elseif($WannaReplace -eq "n"){
echo "Keeping the older installation, quitting..."
Write-Output "Keeping the older installation, quitting..."
}
else{
throw "Wrong Option, use either 'y' or 'n', aborting..."

9249
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
import { Direction, Orientation, QAbstractSliderSignals, QIcon, QLabel } from "@nodegui/nodegui";
import { Direction, Orientation, QAbstractSliderSignals, QIcon } from "@nodegui/nodegui";
import { BoxView, GridColumn, GridRow, GridView, Slider, Text, useEventHandler } from "@nodegui/react-nodegui";
import React, { ReactElement, useContext, useEffect, useRef, useState } from "react";
import React, { ReactElement, useContext, useEffect, useState } from "react";
import playerContext, { CurrentPlaylist } from "../context/playerContext";
import { shuffleArray } from "../helpers/shuffleArray";
import NodeMpv from "node-mpv";
@ -41,7 +41,7 @@ function Player(): ReactElement {
const [currentYtTrack, setCurrentYtTrack] = useState<YoutubeTrack>();
const { addToQueue, isActiveDownloading, isFinishedDownloading } = useDownloadQueue();
const playlistTracksIds = currentPlaylist?.tracks.map((t) => t.track.id);
const playlistTracksIds = currentPlaylist?.tracks?.map((t) => t.track.id) ?? [];
const volumeHandler = useEventHandler<QAbstractSliderSignals>(
{
sliderMoved: (value) => {
@ -54,7 +54,6 @@ function Player(): ReactElement {
[volume]
);
const playerRunning = audioPlayer.isRunning();
const titleRef = useRef<QLabel>();
const cachedPlaylist = localStorage.getItem(LocalStorageKeys.cachedPlaylist);
const cachedTrack = localStorage.getItem(LocalStorageKeys.cachedTrack);
@ -88,7 +87,9 @@ function Player(): ReactElement {
// track change effect
useEffect(() => {
// caching current track
localStorage.setItem(LocalStorageKeys.cachedTrack, JSON.stringify(currentTrack ?? ""));
if(!currentTrack) localStorage.removeItem(LocalStorageKeys.cachedTrack);
else localStorage.setItem(LocalStorageKeys.cachedTrack, JSON.stringify(currentTrack));
(async () => {
try {
if (currentTrack && playerRunning) {
@ -113,7 +114,8 @@ function Player(): ReactElement {
useEffect(() => {
setShuffle(false);
// caching playlist
localStorage.setItem(LocalStorageKeys.cachedPlaylist, JSON.stringify(currentPlaylist ?? ""));
if(!currentPlaylist) localStorage.removeItem(LocalStorageKeys.cachedPlaylist);
else localStorage.setItem(LocalStorageKeys.cachedPlaylist, JSON.stringify(currentPlaylist));
}, [currentPlaylist]);
useEffect(() => {
@ -211,7 +213,7 @@ function Player(): ReactElement {
<GridView enabled={!!currentTrack} style="flex: 1; max-height: 120px;">
<GridRow>
<GridColumn width={2}>
<Text ref={titleRef} wordWrap openExternalLinks>
<Text wordWrap openExternalLinks>
{artistsNames && currentTrack
? `
<p><b><a href="${currentYtTrack?.youtube_uri}"}>${currentTrack.name}</a></b> - ${artistsNames[0]} ${artistsNames.length > 1 ? "feat. " + artistsNames.slice(1).join(", ") : ""}</p>
@ -255,7 +257,11 @@ function Player(): ReactElement {
}}
icon={new QIcon(isFavorite(currentTrack?.id ?? "") ? heart : heartRegular)}
/>
<IconButton style={openLyrics ? "background-color: green;" : ""} icon={new QIcon(musicNode)} on={{ clicked: () => currentTrack && setOpenLyrics(!openLyrics) }} />
<IconButton
style={openLyrics ? "background-color: green;" : ""}
icon={new QIcon(musicNode)}
on={{ clicked: () => currentTrack && setOpenLyrics(!openLyrics) }}
/>
<Slider minSize={{ height: 20, width: 80 }} maxSize={{ height: 20, width: 100 }} hasTracking sliderPosition={volume} on={volumeHandler} orientation={Orientation.Horizontal} />
</BoxView>
</GridColumn>