Skip to content

Instantly share code, notes, and snippets.

@httpJunkie
Last active March 8, 2025 22:41
Show Gist options
  • Save httpJunkie/8c7cc970cfcdd4189bdeabf6f6a43a13 to your computer and use it in GitHub Desktop.
Save httpJunkie/8c7cc970cfcdd4189bdeabf6f6a43a13 to your computer and use it in GitHub Desktop.
playlist-2-YouTube
import os
import tempfile
import shutil
import sys
from mutagen.mp3 import MP3
from pydub import AudioSegment
import ffmpeg
def get_middle_time(input_file, duration):
audio = MP3(input_file)
total_length = audio.info.length
if total_length < duration:
return 0 # If track is shorter than desired clip length, keep it whole
return (total_length - duration) / 2
def create_mixcloud_playlist(playlist_file, output_file):
with open(playlist_file, "r") as f:
tracks = [line.strip() for line in f if line.strip() and not line.startswith("#")]
with open(output_file, "w") as out:
out.write("#\tTrack Number\tArtist\tTrack Title\n") # Corrected header
for i, track in enumerate(tracks, start=1):
artist, title = os.path.splitext(os.path.basename(track))[0].split(" - ")
out.write(f"{i:02d}.\t{artist} - {title}\n") # Format as Artist - Title
print(f"Mixcloud playlist saved as {output_file}")
def append_tracks(playlist_file, middle_duration, image_file=None, format_mixcloud=False, show_full_path=False):
if format_mixcloud:
# Generate the Mixcloud-formatted playlist and exit
output_playlist = os.path.splitext(playlist_file)[0] + "_mixcloud_playlist.txt"
create_mixcloud_playlist(playlist_file, output_playlist)
return # Exit after generating the playlist
temp_dir = tempfile.mkdtemp()
output_file = os.path.splitext(playlist_file)[0] + "_setlist.mp3"
final_audio = AudioSegment.silent(duration=0)
seen_tracks = set()
with open(playlist_file, "r") as f:
tracks = [line.strip() for line in f if line.strip() and not line.startswith("#")]
for i, track in enumerate(tracks, start=1):
track_name = os.path.basename(track) # Get the full track filename
artist, title = os.path.splitext(track_name)[0].split(" - ")
# Only print the full path if the flag is set, otherwise print just Artist - Title
if show_full_path:
print(f"Writing track: {track_name}")
else:
print(f"Writing track: {artist} - {title}")
if track in seen_tracks:
user_input = input(f"Duplicate track found: {track_name}\n(Y) Include only once, (N) Allow duplicates: ")
if user_input.strip().lower() != "y":
final_audio += AudioSegment.from_mp3(track)
continue
seen_tracks.add(track)
start_time = get_middle_time(track, middle_duration)
audio_segment = AudioSegment.from_mp3(track)
trimmed_audio = audio_segment[start_time * 1000 : (start_time + middle_duration) * 1000]
final_audio += trimmed_audio
print("Tracks processed, creating final mixes...")
final_audio.export(output_file, format="mp3")
print(f"Final mix saved as {output_file}")
if image_file:
video_output = os.path.splitext(output_file)[0] + ".mp4"
# Explicitly specify the image and audio input streams
image_input = ffmpeg.input(image_file, loop=1, t=final_audio.duration_seconds)
audio_input = ffmpeg.input(output_file)
# Combine the inputs and output the video with audio
ffmpeg.output(image_input, audio_input, video_output, vcodec='libx264', acodec='aac').run()
print(f"Video created: {video_output}")
shutil.rmtree(temp_dir)
print("Temporary directory cleaned up successfully.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python script.py <playlist.m3u8> [duration] [image] [--formatPlaylistMixcloud] [--showFullAudioPath]")
sys.exit(1)
playlist_file = sys.argv[1]
middle_duration = int(sys.argv[2]) if len(sys.argv) > 2 and not sys.argv[2].startswith("--") else None
image_file = sys.argv[3] if len(sys.argv) > 3 and not sys.argv[3].startswith("--") else None
format_mixcloud = "--formatPlaylistMixcloud" in sys.argv
show_full_path = "--showFullAudioPath" in sys.argv
append_tracks(playlist_file, middle_duration, image_file, format_mixcloud, show_full_path)
"""
## Usage Instructions for mp3append.py
### 1. Generate an audio file of all tracks appended:
This will concatenate all tracks in the playlist into a single audio file.
Usage:
python3 mp3append.py <playlist_file.m3u8>
### 2. Export only the X number of seconds from the middle of each track:
This will create an audio file with only the specified middle duration of each track in the playlist.
Usage:
python3 mp3append.py <playlist_file.m3u8> <middle_duration_in_seconds>
### 3. Export a video along with the audio file for upload to YouTube (or other platforms):
This will create a video where the specified image is looped for the duration of the audio. The audio file will include the middle section of each track.
Usage:
python3 mp3append.py <playlist_file.m3u8> <middle_duration_in_seconds> <image_file>
### 4. Format a playlist for Mixcloud:
This option will output a Mixcloud-friendly text file formatted with track details, ready for use in Mixcloud uploads.
Usage:
python3 mp3append.py <playlist_file.m3u8> --formatPlaylistMixcloud
### 5. Show full audio file path during processing:
By default, only the track name (artist - title) is shown during processing. This flag will show the full file path instead.
Usage:
python3 mp3append.py <playlist_file.m3u8> --showFullAudioPath
### 6. Prevent duplicate tracks from being appended:
If a duplicate track is detected in the playlist, you will be prompted to decide whether to overwrite it or allow duplication.
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment