-
-
Save SpL1Ne/54d8c8d036f58b8afb89eaa34ce77fd0 to your computer and use it in GitHub Desktop.
Split album song file into separate tracks with powershell and ffmpeg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ReadMe | |
# How to use | |
# 1. Put script and ffmpeg.exe into one folder. | |
# 2. Create file with timestamps. | |
# 3. Open powershell terminal. | |
# 4. Execute script: *path\to\script\SplitSong.ps1* *path\to\track* *path\to\file\with\timestamps* | |
# | |
# Example timestamps file: | |
# 00:00 DEVILISH TRIO - As Light Fades (Skeler Remix) | |
# 04:02 Juice WRLD - Conversations (Skeler Remix) | |
# | |
# Example using when album song and chapters in current working directory: | |
# D:\Script\SplitSong.ps1 '.\Downloaded song.mp3' .\chapters.txt | |
# | |
# | |
# Use quotes for paths if it contais spaces. | |
# Script will create folder in current working directory with same name as album track and put there separate tracks. | |
# | |
# Supported format only: [hh:]mm:ss Title | |
# If title contains '-', script will try to split title and add "artist - title" to metadata. | |
# | |
# Tested with Powershell 7.1. | |
# If you want run script on Windows Powershell 5. | |
# Replace | |
# Join-Path $pwd $folderName $trackName | |
# to | |
# Join-Path (Join-Path $pwd $folderName) $trackName | |
# | |
# Also, probably you will have to change execution policy for powershell 5 | |
# Set-ExecutionPolicy RemoteSigned -Scope Process | |
# This command allow to execute scripts for this powershell session. | |
# | |
param( [Parameter(Mandatory = $true)] [string]$songPath, [Parameter(Mandatory = $true)] [string]$chaptersFile ) | |
$chapters = @(Get-Content $chaptersFile) | |
$songfile = Get-ChildItem $songPath | |
$folderName = $songfile.BaseName.Trim().Split([IO.Path]::GetInvalidFileNameChars()) -join '_' | |
if ( -not (Test-Path (Join-Path $pwd $folderName)) ) { New-Item (Join-Path $pwd $folderName) -ItemType Directory > $null } | |
for ($i = 0; $i -lt $chapters.Count; $i++) { | |
$startTime, $trackName = $chapters[$i] -split ' ', 2 | |
$endTime = $trackArtist = '' | |
$trackTitle = $trackName = ($trackName.Trim().Split([IO.Path]::GetInvalidFileNameChars()) -join '_') -replace '\$', '`$' | |
if ($trackName.Contains('-')) { $trackArtist, $trackTitle = $trackName -split '-', 2 } | |
$trackPath = Join-Path $pwd $folderName $trackName | |
if (Test-Path ($trackPath + $songfile.Extension)) { | |
$trackName += "`_$i" | |
$trackPath = Join-Path $pwd $folderName $trackName | |
} | |
$trackPath += $songfile.Extension | |
if ($i -lt $chapters.Count - 1) { | |
$endTime = "-to $(($chapters[$i + 1] -split ' ', 2)[0])" | |
} | |
$command = "ffmpeg -loglevel error -stats -i `"$($songfile.FullName)`" -c:a copy -ss $startTime $endTime -metadata track=`"$($i + 1)`" -metadata title=`"$($trackTitle.Trim())`" -metadata artist=`"$($trackArtist.Trim())`" `"$trackPath`"" | |
Write-Host "Extracting: $trackName" | |
Invoke-Expression $command | |
Write-Host '' | |
Start-Sleep -Milliseconds 500 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment