# ClipForge Helper (Windows PowerShell 5.1+ / PowerShell 7) # Downloads a YouTube (or any yt-dlp supported) link over YOUR internet # connection, uploads the video to ClipForge, and opens the job page. # Also accepts a local video file path (drag the file into this window). # Usage: clipforge-helper.ps1 [URL-or-file] # Env: CLIPFORGE_SERVER, CLIPFORGE_KEEP=1, CLIPFORGE_NO_OPEN=1, CLIPFORGE_NO_PAUSE=1 param([string]$Target = "") $ErrorActionPreference = "Stop" $ProgressPreference = "SilentlyContinue" try { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } catch {} $Server = if ($env:CLIPFORGE_SERVER) { $env:CLIPFORGE_SERVER.TrimEnd('/') } else { "https://clips.thegridreport.news" } $HomeDir = if ($env:CLIPFORGE_HOME) { $env:CLIPFORGE_HOME } else { Join-Path $env:LOCALAPPDATA "ClipForgeHelper" } $Bin = Join-Path $HomeDir "bin" $env:PATH = "$Bin" + [IO.Path]::PathSeparator + $env:PATH $IsWin = ($env:OS -eq "Windows_NT") $YtDlp = Join-Path $Bin ($(if ($IsWin) { "yt-dlp.exe" } else { "yt-dlp" })) if (-not (Test-Path $YtDlp)) { $c = Get-Command yt-dlp -ErrorAction SilentlyContinue; if ($c) { $YtDlp = $c.Source } } function Pause-Exit([int]$code) { if (-not $env:CLIPFORGE_NO_PAUSE) { Read-Host "Press Enter to close this window" | Out-Null } exit $code } function Die([string]$msg) { Write-Host ""; Write-Host "ERROR: $msg" -ForegroundColor Red; Write-Host ""; Pause-Exit 1 } Write-Host "" Write-Host "ClipForge Helper -> $Server" -ForegroundColor Yellow Write-Host "------------------------------------------------------------" $Input2 = $Target if (-not $Input2) { $clip = "" try { $clip = (Get-Clipboard -ErrorAction Stop | Select-Object -First 1) } catch {} if ($clip -and $clip.Trim() -match '^https?://') { $clip = $clip.Trim() Write-Host "Link on your clipboard:"; Write-Host " $clip" $Input2 = Read-Host "Press Enter to use it, or paste a different link / drag a video file here" if (-not $Input2) { $Input2 = $clip } } else { $Input2 = Read-Host "Paste a YouTube link (or drag a video file here), then press Enter" } } $Input2 = $Input2.Trim().Trim('"').Trim("'").Trim() if (-not $Input2) { Die "Nothing entered." } $Work = $null $File = $null try { if ($Input2 -match '^https?://') { if (-not (Test-Path $YtDlp)) { Die "yt-dlp is missing. Re-run the installer from $Server/helper" } $dl = Join-Path $HomeDir "downloads" $Work = Join-Path $dl ("job-" + [guid]::NewGuid().ToString("N").Substring(0, 8)) New-Item -ItemType Directory -Force -Path $Work | Out-Null if (-not $env:CLIPFORGE_NO_UPDATE) { Write-Host "Checking for yt-dlp updates..." try { & $YtDlp -U *> $null } catch {} } $fmt = "bv*[height<=1080]+ba/b[height<=1080]/b" $ff = Get-Command ffmpeg -ErrorAction SilentlyContinue if (-not $ff) { Write-Host "(ffmpeg not found, using a single-file format - quality may be lower)"; $fmt = "b[height<=1080]/b" } Write-Host "Downloading on your computer (this uses your home internet)..." -ForegroundColor Cyan & $YtDlp --no-playlist -f $fmt -S "vcodec:h264,res,acodec:m4a" --merge-output-format mp4 ` --windows-filenames -o (Join-Path $Work "%(title).80B.%(ext)s") $Input2 if ($LASTEXITCODE -ne 0) { Die "The download failed (yt-dlp exit $LASTEXITCODE). If YouTube asks you to sign in, try again in a few minutes or try another video." } $f = Get-ChildItem -LiteralPath $Work -File | Where-Object { $_.Name -notlike "*.part" } | Select-Object -First 1 if (-not $f) { Die "Download finished but no video file was found." } $File = $f.FullName } else { if (-not (Test-Path -LiteralPath $Input2 -PathType Leaf)) { Die "That's not a link and I can't find a file at: $Input2" } $File = (Resolve-Path -LiteralPath $Input2).Path } $info = Get-Item -LiteralPath $File $Size = [int64]$info.Length Write-Host "" Write-Host ("Uploading ""{0}"" ({1} MB) to ClipForge..." -f $info.Name, [math]::Floor($Size / 1MB)) -ForegroundColor Cyan $body = @{ filename = $info.Name; size = $Size } | ConvertTo-Json -Compress try { $r = Invoke-RestMethod -Method Post -Uri "$Server/api/uploads" -ContentType "application/json; charset=utf-8" ` -Body ([Text.Encoding]::UTF8.GetBytes($body)) } catch { Die "ClipForge refused the upload: $($_.Exception.Message) $($_.ErrorDetails.Message)" } $UpId = $r.upload_id; $Chunk = [int]$r.chunk_size if (-not $UpId) { Die "Unexpected reply from ClipForge." } $fs = [IO.File]::OpenRead($File) try { $off = [int64]0 $buf = New-Object byte[] $Chunk while ($off -lt $Size) { [void]$fs.Seek($off, [IO.SeekOrigin]::Begin) $n = 0 while ($n -lt $Chunk) { $k = $fs.Read($buf, $n, $Chunk - $n); if ($k -le 0) { break }; $n += $k } if ($n -eq $Chunk) { $data = $buf } else { $data = New-Object byte[] $n; [Array]::Copy($buf, $data, $n) } $ok = $false; $try = 0; $last = "" while (-not $ok -and $try -lt 6) { $try++ try { $rr = Invoke-RestMethod -Method Put -Uri "$Server/api/uploads/$UpId`?offset=$off" ` -ContentType "application/octet-stream" -Body $data $off = [int64]$rr.received; $ok = $true } catch { $last = "$($_.Exception.Message) $($_.ErrorDetails.Message)" Start-Sleep -Seconds (2 * $try) try { $st = Invoke-RestMethod -Uri "$Server/api/uploads/$UpId"; $off = [int64]$st.received } catch {} } } if (-not $ok) { Die ("Upload kept failing at {0} MB: {1}" -f [math]::Floor($off / 1MB), $last) } Write-Host -NoNewline ("`r {0,3}% ({1} of {2} MB)" -f [math]::Floor($off * 100 / $Size), [math]::Floor($off / 1MB), [math]::Floor($Size / 1MB)) } Write-Host "" } finally { $fs.Close() } try { $fin = Invoke-RestMethod -Method Post -Uri "$Server/api/uploads/$UpId/finish" } catch { Die "Couldn't start the clip job: $($_.Exception.Message) $($_.ErrorDetails.Message)" } $Job = $fin.job_id $Url = "$Server/?job=$Job" Write-Host "" Write-Host "Uploaded! ClipForge job $Job is making your clips." -ForegroundColor Green Write-Host " Opening $Url" Write-Host " (Keep that browser tab open - clips appear there in a few minutes.)" if (-not $env:CLIPFORGE_NO_OPEN) { if ($IsWin) { Start-Process $Url } else { try { Start-Process xdg-open $Url } catch {} } } if ($env:CLIPFORGE_KEEP -and $Work) { Write-Host " Video kept at: $File" } } finally { if ($Work -and -not $env:CLIPFORGE_KEEP -and (Test-Path $Work)) { Remove-Item -Recurse -Force -LiteralPath $Work -ErrorAction SilentlyContinue } } Write-Host "" Pause-Exit 0