Initial Commit

This commit is contained in:
Mark Gregory
2026-10-19 15:29:27 +01:00
commit a665a31ff3
7 changed files with 191 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
.idea
+10
View File
@@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PackageRequirementsSettings" />
<component name="PyDocumentationSettings" />
<component name="ReSTService" />
<component name="TestRunnerService" />
</module>
+6
View File
@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Music.iml" filepath="$PROJECT_DIR$/.idea/Music.iml" />
</modules>
</component>
</project>
+151
View File
@@ -0,0 +1,151 @@
#!/usr/bin/env python3
import argparse
import re
import subprocess
import tempfile
from pathlib import Path
EXTENSIONS = {
".mp3", ".m4a", ".wav", ".flac",
".aac", ".ogg", ".aiff", ".aif"
}
def run(command):
subprocess.run(command, check=True)
def create_snippets(
source,
output,
snippet_seconds=8,
silence_seconds=4
):
source = Path(source).expanduser().resolve()
output = Path(output).expanduser().resolve()
if not source.is_dir():
raise SystemExit(f"Folder not found: {source}")
if snippet_seconds <= 0 or silence_seconds < 0:
raise SystemExit("Invalid snippet or silence duration")
tracks = sorted(
(
p for p in source.iterdir()
if p.is_file()
and p.suffix.lower() in EXTENSIONS
and p != output
),
key=lambda p: [
int(part) if part.isdigit() else part.lower()
for part in re.split(r"(\d+)", p.name)
]
)
if not tracks:
raise SystemExit("No supported audio files found")
print(f"Found {len(tracks)} tracks")
output.parent.mkdir(parents=True, exist_ok=True)
with tempfile.TemporaryDirectory() as temp:
temp = Path(temp)
segments = []
for index, track in enumerate(tracks, start=1):
print(f"[{index}/{len(tracks)}] {track.name}")
snippet = temp / f"snippet_{index:04d}.wav"
run([
"ffmpeg",
"-hide_banner",
"-loglevel", "error",
"-y",
"-i", str(track),
"-t", str(snippet_seconds),
"-vn",
"-ac", "2",
"-ar", "44100",
"-c:a", "pcm_s16le",
str(snippet)
])
segments.append(snippet)
if index < len(tracks) and silence_seconds > 0:
silence = temp / f"silence_{index:04d}.wav"
run([
"ffmpeg",
"-hide_banner",
"-loglevel", "error",
"-y",
"-f", "lavfi",
"-i",
"anullsrc=r=44100:cl=stereo",
"-t", str(silence_seconds),
"-c:a", "pcm_s16le",
str(silence)
])
segments.append(silence)
playlist = temp / "playlist.txt"
playlist.write_text(
"".join(
f"file '{str(segment)}'\n"
for segment in segments
)
)
print("Combining snippets...")
run([
"ffmpeg",
"-hide_banner",
"-loglevel", "error",
"-y",
"-f", "concat",
"-safe", "0",
"-i", str(playlist),
"-c:a", "libmp3lame",
"-b:a", "192k",
str(output)
])
print()
print("Complete!")
print(f"Output: {output}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("source")
parser.add_argument("output")
parser.add_argument(
"--snippet",
type=float,
default=5
)
parser.add_argument(
"--silence",
type=float,
default=5
)
args = parser.parse_args()
create_snippets(
args.source,
args.output,
args.snippet,
args.silence
)
Executable
+3
View File
@@ -0,0 +1,3 @@
python3 "/Volumes/Developer/Applications/Music/audio_snippets.py" \
"/Users/markgregory/Music/Sunnify/Christmas Songs - Mark-Gregory" \
"$HOME/Downloads/christmas_comp.mp3"