mirror of
https://github.com/darkzoul5/YoutubePlaylistSync.git
synced 2026-07-03 12:34:00 +03:00
Merge branch 'main' of https://git.darkzoul.org/dark_zoul/YouTube-Playlist-Downloader
This commit is contained in:
@@ -2,52 +2,14 @@ name: Build Release Packages
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
#branches:
|
||||||
- main
|
#- main
|
||||||
#tags:
|
tags:
|
||||||
#- "v*"
|
- "v*.*.*"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
determine-next-tag:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
next_tag: ${{ steps.set_tag.outputs.next_tag }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: https://gitea.com/actions/checkout@v5
|
|
||||||
|
|
||||||
- name: Determine next version tag
|
|
||||||
id: set_tag
|
|
||||||
run: |
|
|
||||||
git fetch --tags
|
|
||||||
|
|
||||||
LATEST_TAG=$(git tag -l "v*.*.*" | sort -V | tail -n1)
|
|
||||||
echo "Latest tag: $LATEST_TAG"
|
|
||||||
|
|
||||||
if [ -z "$LATEST_TAG" ]; then
|
|
||||||
NEXT_TAG="v0.0.1"
|
|
||||||
else
|
|
||||||
PATCH=$(echo $LATEST_TAG | awk -F. '{print $3}')
|
|
||||||
MAJOR=$(echo $LATEST_TAG | awk -F. '{print $1}' | tr -d 'v')
|
|
||||||
MINOR=$(echo $LATEST_TAG | awk -F. '{print $2}')
|
|
||||||
PATCH=$((PATCH+1))
|
|
||||||
NEXT_TAG="v${MAJOR}.${MINOR}.${PATCH}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Next tag: $NEXT_TAG"
|
|
||||||
echo "next_tag=$NEXT_TAG" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Create new tag
|
|
||||||
run: |
|
|
||||||
git config user.name "Gitea Actions"
|
|
||||||
git config user.email "actions@gitea.local"
|
|
||||||
git tag ${{ steps.set_tag.outputs.next_tag }}
|
|
||||||
git push origin ${{ steps.set_tag.outputs.next_tag }}
|
|
||||||
|
|
||||||
|
|
||||||
windows-package:
|
windows-package:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: determine-next-tag
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: https://gitea.com/actions/checkout@v5
|
uses: https://gitea.com/actions/checkout@v5
|
||||||
@@ -63,46 +25,60 @@ jobs:
|
|||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install -y unzip zip curl
|
sudo apt install -y unzip zip curl
|
||||||
|
|
||||||
|
- name: Extract tag name
|
||||||
|
run: |
|
||||||
|
REF="${GITEA_REF:-$GITHUB_REF}"
|
||||||
|
TAG="${REF#refs/tags/}"
|
||||||
|
echo "TAG=$TAG" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Prepare Windows package
|
- name: Prepare Windows package
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
mkdir -p dist/windows
|
WORKSPACE_ROOT="${GITEA_WORKSPACE:-$PWD}"
|
||||||
cp yt-playlist-main.py dist/windows/
|
mkdir -p "$WORKSPACE_ROOT/dist/windows"
|
||||||
cp yt-playlist-config.json dist/windows/
|
cp "$WORKSPACE_ROOT/yt-playlist-main.py" "$WORKSPACE_ROOT/dist/windows/"
|
||||||
|
cp "$WORKSPACE_ROOT/yt-playlist-config.json" "$WORKSPACE_ROOT/dist/windows/"
|
||||||
|
|
||||||
mkdir -p dist/windows/bin
|
mkdir -p "$WORKSPACE_ROOT/dist/windows/bin"
|
||||||
|
|
||||||
# yt-dlp
|
# yt-dlp
|
||||||
curl -L -o dist/windows/bin/yt-dlp.exe https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe
|
curl -L -o "$WORKSPACE_ROOT/dist/windows/bin/yt-dlp.exe" https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe
|
||||||
|
|
||||||
# FFmpeg Windows static
|
# FFmpeg Windows static
|
||||||
curl -L -o dist/windows/ffmpeg.zip https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip
|
curl -L -o "$WORKSPACE_ROOT/dist/windows/ffmpeg.zip" https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip
|
||||||
unzip -q dist/windows/ffmpeg.zip -d dist/windows/ffmpeg_temp
|
unzip -q "$WORKSPACE_ROOT/dist/windows/ffmpeg.zip" -d "$WORKSPACE_ROOT/dist/windows/ffmpeg_temp"
|
||||||
mv $(find dist/windows/ffmpeg_temp -name ffmpeg.exe | head -n 1) dist/windows/bin/ffmpeg.exe
|
mv $(find "$WORKSPACE_ROOT/dist/windows/ffmpeg_temp" -name ffmpeg.exe | head -n 1) "$WORKSPACE_ROOT/dist/windows/bin/ffmpeg.exe"
|
||||||
|
|
||||||
# aria2c Windows static
|
# aria2c Windows static
|
||||||
curl -L -o dist/windows/aria2c.zip https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0-win-64bit-build1.zip
|
curl -L -o "$WORKSPACE_ROOT/dist/windows/aria2c.zip" https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0-win-64bit-build1.zip
|
||||||
unzip dist/windows/aria2c.zip -d dist/windows/
|
unzip "$WORKSPACE_ROOT/dist/windows/aria2c.zip" -d "$WORKSPACE_ROOT/dist/windows/"
|
||||||
mv dist/windows/aria2-1.37.0-win-64bit-build1/aria2c.exe dist/windows/bin/aria2c.exe
|
mv "$WORKSPACE_ROOT/dist/windows/aria2-1.37.0-win-64bit-build1/aria2c.exe" "$WORKSPACE_ROOT/dist/windows/bin/aria2c.exe"
|
||||||
|
|
||||||
# Remove temp files before zipping
|
# Remove temp files before zipping
|
||||||
rm -rf dist/windows/ffmpeg_temp dist/windows/aria2-1.37.0-win-64bit-build1 dist/windows/ffmpeg.zip dist/windows/aria2c.zip dist/windows/aria2c.zip
|
rm -rf "$WORKSPACE_ROOT/dist/windows/ffmpeg_temp" "$WORKSPACE_ROOT/dist/windows/aria2-1.37.0-win-64bit-build1" "$WORKSPACE_ROOT/dist/windows/ffmpeg.zip" "$WORKSPACE_ROOT/dist/windows/aria2c.zip"
|
||||||
|
|
||||||
# Zip everything
|
cd "$WORKSPACE_ROOT/dist/windows"
|
||||||
cd dist/windows
|
ZIP_NAME="yt-playlist-windows-${TAG}.zip"
|
||||||
zip -r ../../yt-playlist-windows-${{ needs.determine-next-tag.outputs.next_tag }}.zip *
|
zip -r "$WORKSPACE_ROOT/$ZIP_NAME" *
|
||||||
cd ../..
|
echo "ZIP_PATH=$WORKSPACE_ROOT/$ZIP_NAME" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Upload Windows release
|
- name: Upload Windows release
|
||||||
uses: https://gitea.com/actions/gitea-release-action@v1
|
uses: https://gitea.com/actions/gitea-release-action@v1
|
||||||
with:
|
with:
|
||||||
files: yt-playlist-windows-${{ needs.determine-next-tag.outputs.next_tag }}.zip
|
files: ${{ env.ZIP_PATH }}
|
||||||
tag_name: ${{ needs.determine-next-tag.outputs.next_tag }}
|
tag_name: ${{ env.TAG }}
|
||||||
name: ${{ needs.determine-next-tag.outputs.next_tag }}
|
name: ${{ env.TAG }}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
linux-package:
|
linux-package:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: determine-next-tag
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: https://gitea.com/actions/checkout@v5
|
uses: https://gitea.com/actions/checkout@v5
|
||||||
@@ -116,10 +92,15 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
pip install --upgrade pip
|
pip install --upgrade pip
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install -y \
|
sudo apt install -y unzip zip curl wget build-essential \
|
||||||
unzip zip curl wget build-essential pkg-config \
|
pkg-config libssl-dev zlib1g-dev
|
||||||
autoconf automake libtool gettext autopoint \
|
|
||||||
libssl-dev libxml2-dev zlib1g-dev libsqlite3-dev
|
|
||||||
|
- name: Extract tag name
|
||||||
|
run: |
|
||||||
|
REF="${GITEA_REF:-$GITHUB_REF}"
|
||||||
|
TAG="${REF#refs/tags/}"
|
||||||
|
echo "TAG=$TAG" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Build aria2c Linux static
|
- name: Build aria2c Linux static
|
||||||
run: |
|
run: |
|
||||||
@@ -139,39 +120,55 @@ jobs:
|
|||||||
- name: Prepare Linux package
|
- name: Prepare Linux package
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
mkdir -p dist/linux
|
WORKSPACE_ROOT="${GITEA_WORKSPACE:-$PWD}"
|
||||||
cp yt-playlist-main.py dist/linux/
|
mkdir -p "$WORKSPACE_ROOT/dist/linux"
|
||||||
cp yt-playlist-config.json dist/linux/
|
cp "$WORKSPACE_ROOT/yt-playlist-main.py" "$WORKSPACE_ROOT/dist/linux/"
|
||||||
|
cp "$WORKSPACE_ROOT/yt-playlist-config.json" "$WORKSPACE_ROOT/dist/linux/"
|
||||||
|
|
||||||
mkdir -p dist/linux/bin
|
mkdir -p "$WORKSPACE_ROOT/dist/linux/bin"
|
||||||
|
|
||||||
# yt-dlp
|
# yt-dlp
|
||||||
curl -L -o dist/linux/bin/yt-dlp https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux
|
curl -L -o "$WORKSPACE_ROOT/dist/linux/bin/yt-dlp" https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux
|
||||||
chmod +x dist/linux/bin/yt-dlp
|
chmod +x "$WORKSPACE_ROOT/dist/linux/bin/yt-dlp"
|
||||||
|
|
||||||
# FFmpeg Linux static
|
# FFmpeg Linux static
|
||||||
curl -L -o dist/linux/ffmpeg.tar.xz https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz
|
curl -L -o "$WORKSPACE_ROOT/dist/linux/ffmpeg.tar.xz" https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz
|
||||||
mkdir -p dist/linux/ffmpeg_temp
|
mkdir -p "$WORKSPACE_ROOT/dist/linux/ffmpeg_temp"
|
||||||
tar -xf dist/linux/ffmpeg.tar.xz -C dist/linux/ffmpeg_temp --strip-components=1
|
tar -xf "$WORKSPACE_ROOT/dist/linux/ffmpeg.tar.xz" -C "$WORKSPACE_ROOT/dist/linux/ffmpeg_temp" --strip-components=1
|
||||||
mv dist/linux/ffmpeg_temp/ffmpeg dist/linux/bin/ffmpeg
|
mv "$WORKSPACE_ROOT/dist/linux/ffmpeg_temp/ffmpeg" "$WORKSPACE_ROOT/dist/linux/bin/ffmpeg"
|
||||||
chmod +x dist/linux/bin/ffmpeg
|
chmod +x "$WORKSPACE_ROOT/dist/linux/bin/ffmpeg"
|
||||||
|
|
||||||
# Copy built aria2c binary if present
|
# aria2c minimal fully static
|
||||||
if [ -f dist/linux/bin/aria2c ]; then
|
mkdir -p "$WORKSPACE_ROOT/dist/linux/aria2c_build"
|
||||||
chmod +x dist/linux/bin/aria2c
|
cd "$WORKSPACE_ROOT"
|
||||||
fi
|
wget https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0.tar.gz
|
||||||
|
tar -xzf aria2-1.37.0.tar.gz
|
||||||
|
cd aria2-1.37.0
|
||||||
|
CFLAGS="-Os -s" LDFLAGS="-static" ./configure \
|
||||||
|
--enable-static --disable-shared \
|
||||||
|
--disable-libaria2 --without-ca-bundle \
|
||||||
|
--without-libnettle --without-libgcrypt \
|
||||||
|
--without-libssh2 --without-libexpat \
|
||||||
|
--without-libxml2 --without-libsqlite3 \
|
||||||
|
--with-openssl
|
||||||
|
make -j"$(nproc)"
|
||||||
|
strip src/aria2c
|
||||||
|
|
||||||
|
cp src/aria2c "$WORKSPACE_ROOT/dist/linux/bin/aria2c"
|
||||||
|
chmod +x "$WORKSPACE_ROOT/dist/linux/bin/aria2c"
|
||||||
|
|
||||||
# Remove temp files and downloaded archives before zipping
|
# Cleanup
|
||||||
rm -rf dist/linux/ffmpeg_temp dist/linux/aria2c_build dist/linux/ffmpeg.tar.xz dist/linux/aria2c_build/aria2-1.37.0.tar.gz
|
rm -rf "$WORKSPACE_ROOT/dist/linux/ffmpeg_temp" "$WORKSPACE_ROOT/dist/linux/aria2c_build" "$WORKSPACE_ROOT/dist/linux/ffmpeg.tar.xz" "$WORKSPACE_ROOT/aria2-1.37.0" "$WORKSPACE_ROOT/aria2-1.37.0.tar.gz"
|
||||||
|
|
||||||
# Zip everything at top level
|
# Zip everything
|
||||||
cd dist/linux
|
cd "$WORKSPACE_ROOT/dist/linux"
|
||||||
zip -r ../../yt-playlist-linux-${{ needs.determine-next-tag.outputs.next_tag }}.zip *
|
ZIP_NAME="yt-playlist-linux-${TAG}.zip"
|
||||||
cd ../..
|
zip -r "$WORKSPACE_ROOT/$ZIP_NAME" *
|
||||||
|
echo "ZIP_PATH=$WORKSPACE_ROOT/$ZIP_NAME" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Upload Linux release
|
- name: Upload Linux release
|
||||||
uses: https://gitea.com/actions/gitea-release-action@v1
|
uses: https://gitea.com/actions/gitea-release-action@v1
|
||||||
with:
|
with:
|
||||||
files: yt-playlist-linux-${{ needs.determine-next-tag.outputs.next_tag }}.zip
|
files: ${{ env.ZIP_PATH }}
|
||||||
tag_name: ${{ needs.determine-next-tag.outputs.next_tag }}
|
tag_name: ${{ env.TAG }}
|
||||||
name: ${{ needs.determine-next-tag.outputs.next_tag }}
|
name: ${{ env.TAG }}
|
||||||
@@ -1,3 +1,112 @@
|
|||||||
# YouTube-Playlist-Downloader
|
# YouTube Playlist Downloader
|
||||||
|
|
||||||
Little app to download music playlists from YouTube
|
A cross-platform tool and workflow for downloading entire YouTube playlists as MP3 files, using [yt-dlp](https://github.com/yt-dlp/yt-dlp), [ffmpeg](https://ffmpeg.org/), and [aria2c](https://github.com/aria2/aria2). Includes Gitea CI/CD workflow for packaging and releasing Windows and Linux binaries.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Download full YouTube playlists** as high-quality MP3 files.
|
||||||
|
- **Parallel downloads** using aria2c for speed.
|
||||||
|
- **Automatic numbering:** numbers tracks same as the origin playlist.
|
||||||
|
- **Cleanup of tracks:** optioon to remove tracks not in playlist anymore.
|
||||||
|
- **Configurable output paths** and archive tracking.
|
||||||
|
- **Cross-platform:** Windows and Linux support.
|
||||||
|
- **Gitea CI/CD workflow** for automated packaging and release.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Python 3.8+
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Quick Start
|
||||||
|
|
||||||
|
1. **Download the latest release:**
|
||||||
|
- Go to the [Releases](https://git.darkzoul.org/dark_zoul/YouTube-Playlist-Downloader/releases) page.
|
||||||
|
- Download the appropriate archive for your platform (Windows or Linux).
|
||||||
|
|
||||||
|
2. **Unzip the archive:**
|
||||||
|
- Extract the contents to a folder of your choice.
|
||||||
|
|
||||||
|
3. **Edit configuration:**
|
||||||
|
- Open `yt-playlist-config.json` and adjust paths and playlist URLs as needed.
|
||||||
|
|
||||||
|
4. **Run the downloader:**
|
||||||
|
- On Windows:
|
||||||
|
```sh
|
||||||
|
python yt-playlist-main.py
|
||||||
|
```
|
||||||
|
- On Linux:
|
||||||
|
```sh
|
||||||
|
python3 yt-playlist-main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
Edit `yt-playlist-config.json` to specify playlists and paths:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"playlists": [
|
||||||
|
{
|
||||||
|
"url": "https://www.youtube.com/playlist?list=playlistidhere",
|
||||||
|
"save_path": "./music",
|
||||||
|
"archive": "archive.txt"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"yt_dlp_path": "./bin/yt-dlp.exe",
|
||||||
|
"ffmpeg_path": "./bin/ffmpeg.exe",
|
||||||
|
"aria2c_path": "./bin/aria2c.exe",
|
||||||
|
"max_parallel_downloads": 10,
|
||||||
|
"aria2c_connections": 8
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **playlists:** List of playlist objects. Each must have a `url`, `save_path`, and `archive`.
|
||||||
|
- **yt_dlp_path, ffmpeg_path, aria2c_path:** Paths to binaries (relative or absolute).
|
||||||
|
- **max_parallel_downloads:** Number of simultaneous downloads.
|
||||||
|
- **aria2c_connections:** Connections per download.
|
||||||
|
|
||||||
|
### Running
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python yt-playlist-main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
- The script will check for binaries, update yt-dlp, and download all new tracks in the playlist.
|
||||||
|
- Tracks are saved and numbered in the specified folder.
|
||||||
|
- Deleted/private videos are skipped.
|
||||||
|
- Archive file prevents re-downloading existing tracks.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- **No binaries found:** Ensure paths in `yt-playlist-config.json` are correct.
|
||||||
|
- **No tracks downloaded:** Check playlist URL and archive file.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
- [yt-dlp](https://github.com/yt-dlp/yt-dlp)
|
||||||
|
- [ffmpeg](https://ffmpeg.org/)
|
||||||
|
- [aria2c](https://github.com/aria2/aria2)
|
||||||
|
|
||||||
|
---
|
||||||
Reference in New Issue
Block a user