Created
December 16, 2025 15:44
-
-
Save hiroto-takatoshi/2c2c1d3fe38a024015dfaa2b0117e53f to your computer and use it in GitHub Desktop.
Podcast Downloader Script
This file contains hidden or 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
| #!/bin/bash | |
| # Podcast Downloader Script | |
| # Downloads audio from Twitter/YouTube and uploads to Google Drive | |
| set -e | |
| # Colors for output | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' # No Color | |
| # Default values | |
| URL="" | |
| FILENAME="" | |
| KEEP_FILE=false | |
| INTERACTIVE=true | |
| # Function to show usage | |
| show_help() { | |
| echo "Usage: $0 [OPTIONS]" | |
| echo "" | |
| echo "Download podcast audio from Twitter/YouTube and upload to Google Drive" | |
| echo "" | |
| echo "Options:" | |
| echo " -u, --url URL URL to download (Twitter/YouTube) [required]" | |
| echo " -f, --filename NAME Custom filename (optional, auto-generated if not provided)" | |
| echo " -k, --keep Keep local file after upload (default: delete)" | |
| echo " -h, --help Show this help message" | |
| echo "" | |
| echo "Examples:" | |
| echo " $0 -u https://x.com/user/status/123" | |
| echo " $0 -u https://youtube.com/watch?v=abc -f my-podcast" | |
| echo " $0 -u https://x.com/user/status/123 -f episode-1 -k" | |
| exit 0 | |
| } | |
| # Parse command line arguments | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -u|--url) | |
| URL="$2" | |
| INTERACTIVE=false | |
| shift 2 | |
| ;; | |
| -f|--filename) | |
| FILENAME="$2" | |
| INTERACTIVE=false | |
| shift 2 | |
| ;; | |
| -k|--keep) | |
| KEEP_FILE=true | |
| INTERACTIVE=false | |
| shift | |
| ;; | |
| -h|--help) | |
| show_help | |
| ;; | |
| *) | |
| echo "Unknown option: $1" | |
| show_help | |
| ;; | |
| esac | |
| done | |
| echo -e "${BLUE}=== Podcast Downloader ===${NC}\n" | |
| # Check for yt-dlp updates | |
| echo -e "${YELLOW}Checking for yt-dlp updates...${NC}" | |
| if command -v yt-dlp &> /dev/null; then | |
| CURRENT_VERSION=$(yt-dlp --version 2>/dev/null || echo "unknown") | |
| echo "Current version: $CURRENT_VERSION" | |
| # Check if update is available and update | |
| UPDATE_OUTPUT=$(yt-dlp -U 2>&1 || true) | |
| if echo "$UPDATE_OUTPUT" | grep -q "Updating\|Updated"; then | |
| echo -e "${GREEN}yt-dlp updated successfully${NC}\n" | |
| else | |
| echo -e "${GREEN}yt-dlp is up to date${NC}\n" | |
| fi | |
| else | |
| echo -e "${YELLOW}Error: yt-dlp not found. Please install it first.${NC}" | |
| exit 1 | |
| fi | |
| # Get URL from user (if not provided via CLI) | |
| if [ -z "$URL" ]; then | |
| read -p "Enter URL (Twitter/YouTube): " URL | |
| if [ -z "$URL" ]; then | |
| echo "Error: URL cannot be empty" | |
| exit 1 | |
| fi | |
| fi | |
| # Get optional filename (if not provided via CLI) | |
| if [ -z "$FILENAME" ] && [ "$INTERACTIVE" = true ]; then | |
| read -p "Enter filename (optional, press Enter to auto-generate): " FILENAME | |
| fi | |
| # Check if rclone is configured | |
| if ! command -v rclone &> /dev/null; then | |
| echo -e "${YELLOW}Error: rclone not found. Please install it first.${NC}" | |
| exit 1 | |
| fi | |
| # Check if gdrive remote exists | |
| if ! rclone listremotes | grep -q "gdrive:"; then | |
| echo -e "${YELLOW}Error: Google Drive remote not configured. Please run 'rclone config' first.${NC}" | |
| exit 1 | |
| fi | |
| # Check if podcasts folder exists, create if not | |
| if ! rclone lsd gdrive: | grep -q "podcasts"; then | |
| echo -e "${YELLOW}Creating podcasts folder in Google Drive...${NC}" | |
| rclone mkdir gdrive:podcasts | |
| fi | |
| # Download audio | |
| echo -e "\n${BLUE}Downloading audio at 128k bitrate...${NC}" | |
| if [ -z "$FILENAME" ]; then | |
| # Auto-generate filename | |
| yt-dlp -x --audio-format m4a --audio-quality 128K "$URL" | |
| # Get the downloaded filename (most recently modified audio file) | |
| DOWNLOADED_FILE=$(ls -t *.m4a 2>/dev/null | head -1) | |
| else | |
| # Use custom filename - add extension if not provided | |
| if [[ "$FILENAME" != *.* ]]; then | |
| FILENAME="${FILENAME}.m4a" | |
| fi | |
| # Download to temp location first to get the actual format | |
| TEMP_DIR=$(mktemp -d) | |
| yt-dlp -x --audio-format m4a --audio-quality 128K -o "$TEMP_DIR/temp.%(ext)s" "$URL" | |
| # Get the actual downloaded file | |
| ACTUAL_FILE=$(find "$TEMP_DIR" -type f -name "*.m4a" | head -1) | |
| if [ -n "$ACTUAL_FILE" ]; then | |
| # Use user's filename with m4a extension | |
| DOWNLOADED_FILE="${FILENAME%.*}.m4a" | |
| mv "$ACTUAL_FILE" "$DOWNLOADED_FILE" | |
| else | |
| echo -e "${YELLOW}Error: Could not determine downloaded file format${NC}" | |
| rm -rf "$TEMP_DIR" | |
| exit 1 | |
| fi | |
| rm -rf "$TEMP_DIR" | |
| fi | |
| if [ ! -f "$DOWNLOADED_FILE" ]; then | |
| echo -e "${YELLOW}Error: Download failed or file not found${NC}" | |
| exit 1 | |
| fi | |
| echo -e "${GREEN}Download complete: $DOWNLOADED_FILE${NC}" | |
| # Upload to Google Drive | |
| echo -e "\n${BLUE}Uploading to Google Drive /podcasts...${NC}" | |
| rclone copy "$DOWNLOADED_FILE" gdrive:podcasts/ | |
| echo -e "${GREEN}Upload complete!${NC}" | |
| echo -e "\nFile location: gdrive:podcasts/$DOWNLOADED_FILE" | |
| # Handle local file cleanup | |
| if [ "$INTERACTIVE" = true ]; then | |
| read -p "Keep local file? (y/n, default: n): " KEEP_FILE_INPUT | |
| if [ "$KEEP_FILE_INPUT" = "y" ] || [ "$KEEP_FILE_INPUT" = "Y" ]; then | |
| KEEP_FILE=true | |
| fi | |
| fi | |
| if [ "$KEEP_FILE" = true ]; then | |
| echo -e "${GREEN}Local file kept: $DOWNLOADED_FILE${NC}" | |
| else | |
| rm "$DOWNLOADED_FILE" | |
| echo -e "${GREEN}Local file removed${NC}" | |
| fi | |
| echo -e "\n${GREEN}Done!${NC}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment