{"id":13533703,"url":"https://github.com/Schroedinger-Hat/youtube-to-spotify","last_synced_at":"2025-04-01T22:30:32.556Z","repository":{"id":38950129,"uuid":"290900709","full_name":"Schroedinger-Hat/youtube-to-spotify","owner":"Schroedinger-Hat","description":"An automation process to convert YouTube video into audio file and uploading it to Anchor.fm podcast","archived":false,"fork":false,"pushed_at":"2025-03-18T15:37:13.000Z","size":17091,"stargazers_count":134,"open_issues_count":8,"forks_count":73,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-30T04:15:16.575Z","etag":null,"topics":["actions","actionshackathon","anchor","automation","devops","docker","github-actions","hacktoberfest","podcast","podcasting","podcasts","puppeteer","spotify","youtube-dl"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Schroedinger-Hat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":"schrodinger-hat","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-08-27T23:08:21.000Z","updated_at":"2025-03-18T15:37:19.000Z","dependencies_parsed_at":"2023-01-04T12:17:47.846Z","dependency_job_id":"c0d7c3c3-f098-433f-8cd5-8d312b1bff14","html_url":"https://github.com/Schroedinger-Hat/youtube-to-spotify","commit_stats":{"total_commits":281,"total_committers":15,"mean_commits":"18.733333333333334","dds":0.604982206405694,"last_synced_commit":"474b7e9597f1c46715e684cbe970ef4a96e56749"},"previous_names":["schroedinger-hat/youtube-to-anchorfm","schroedinger-hat/youtube-to-spotify"],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Schroedinger-Hat%2Fyoutube-to-spotify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Schroedinger-Hat%2Fyoutube-to-spotify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Schroedinger-Hat%2Fyoutube-to-spotify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Schroedinger-Hat%2Fyoutube-to-spotify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Schroedinger-Hat","download_url":"https://codeload.github.com/Schroedinger-Hat/youtube-to-spotify/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246720416,"owners_count":20822898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions","actionshackathon","anchor","automation","devops","docker","github-actions","hacktoberfest","podcast","podcasting","podcasts","puppeteer","spotify","youtube-dl"],"created_at":"2024-08-01T07:01:22.327Z","updated_at":"2025-04-01T22:30:32.549Z","avatar_url":"https://github.com/Schroedinger-Hat.png","language":"JavaScript","funding_links":["https://opencollective.com/schrodinger-hat"],"categories":["Community Resources"],"sub_categories":["Deployment"],"readme":"# Y2S = YouTube to Spotify - An automation tool to publish your podcast\n\n![Cover image](https://raw.githubusercontent.com/schroedinger-Hat/youtube-to-anchorfm/main/assets/img/cover.png 'Cover image')\n\nThis action will upload an audio file from a given YouTube video automatically to your spotify account.\n\nIt is very useful in a scenario where you have a YouTube account and also a podcast at Spotify through Anchor.fm.\n\nIn our live show ([Schrödinger Hat](https://open.spotify.com/show/7yfkQCV6hrPIqflSqJDB2P)) we had this necessity. So we built it for the open source community.\n\nEvery contribution is appreciated, even just a simple feedback.\n\nTable of Contents\n=================\n\n* [YouTube to spotify - An automation tool to publish your podcast](#youtube-to-spotify---an-automation-tool-to-publish-your-podcast)\n   * [How it works](#how-it-works)\n   * [How can I run this as a GitHub action?](#how-can-i-run-this-as-a-github-action)\n   * [Environment variables](#environment-variables)\n      * [Draft Mode](#draft-mode)\n      * [Audio conversion options](#audio-conversion-options)\n      * [Explicit Mode](#explicit-mode)\n      * [Thumbnail Mode](#thumbnail-mode)\n      * [Add YouTube URL to Podcast Description](#add-youtube-url-to-podcast-description)\n      * [Set a publish date for the episode](#set-a-publish-date-for-the-episode)\n  * [Multiple shows per repository](#multiple-shows-per-repository)\n   * [How can I setup for development and use the script locally?](#how-can-i-setup-for-development-and-use-the-script-locally)\n   * [How to upload a YouTube playlist to spotify using this script?](#how-to-upload-a-youtube-playlist-to-spotify-using-this-script)\n* [Contributors](#contributors)\n* [License](#license)\n\n\n## How it works\n\nThe action will start every time you push a change on the `episode.json` file. Into this file you need to specify the YouTube id of your video.\n\nThe action uses a docker image built over Ubuntu. It takes some time to setup the environment before running the script.\n\n**NOTE**: For the script to run successfully it is necessary for there to be at least one episode manually published on spotify, as the steps to publish on a brand new spotify account are different, and the automation will break.\n\n## How can I run this as a GitHub action?\n\nYou can use the latest version of this action from the [GitHub Actions marketplace](https://github.com/marketplace/actions/upload-episode-from-youtube-to-spotify).\n\nIn the repository root directory add a `episode.json` file containing your YouTube video id, e.g.:\n\n```json\n{\n  \"id\": \"nHCXZC2InAA\"\n}\n```\n\nThen create a GitHub action in the `.github/workflows` directory with this yaml:\n\n```yaml\nname: 'Upload Episode from YouTube To Spotify'\n\non:\n  push:\n    paths:\n      - episode.json\n    branches: [main]\n\njobs:\n  upload_episode:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - name: Upload Episode from YouTube To Spotify\n        uses: Schroedinger-Hat/youtube-to-spotify@v2.5.0\n        env:\n          SPOTIFY_EMAIL: ${{ secrets.SPOTIFY_EMAIL }}\n          SPOTIFY_PASSWORD: ${{ secrets.SPOTIFY_PASSWORD }}\n          EPISODE_PATH: /github/workspace\n```\n\n**NOTE**: you need to [set up the secrets](https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository) for _SPOTIFY_EMAIL_ and _SPOTIFY_PASSWORD_. This environment variables are mandatory as they specify the sign in account. \n\n**NOTE**: Since [PR#127](https://github.com/Schroedinger-Hat/youtube-to-anchorfm/issues/127) the project remove any reference to Anchor.fm due to the Spotify acquisition of the company (you can read more [here](https://medium.com/anchor/anchor-is-joining-spotify-70356e3ac23f)).\n\n## Environment variables\n\n### Login Type\n\nSetting the `SPOTIFY_LOGIN` to true makes the script login with the old spotify login type. Instead setting it to false makes the script login with the spotify account. By default the value is true.\n\n```yaml\nenv:\n  SPOTIFY_LOGIN: true\n```\n\n### Draft Mode\n\nBy setting the `SAVE_AS_DRAFT`, the new episode will be published as a draft. This can be useful if you need someone else's\napproval before actual publication.\n\n```yaml\nenv:\n  SAVE_AS_DRAFT: true\n```\n\n### Audio conversion options\n\nffmpeg is used to convert the video to MP3. It's possible to pass arguments to ffmpeg with `POSTPROCESSOR_ARGS` environment\nvariable.\n\nSee `-postprocessor-args` syntax and options on https://github.com/yt-dlp/yt-dlp#post-processing-options.\n\nThe example below convert the video to mono audio.\n\n```yaml\nenv:\n  POSTPROCESSOR_ARGS: 'ExtractAudio+ffmpeg:-ac 1'\n```\n\nTo convert to mono audio, remove initial silence and apply fade-in:\n\n```yaml\n# remove initial silence quieter than -50dB\nenv:\n  POSTPROCESSOR_ARGS: \"ExtractAudio+ffmpeg:-ac 1 -af silenceremove=1:0:-50dB,afade=t=in:d=5\"\n```\n\n### Explicit Mode\n\nBy setting the `IS_EXPLICIT`, the new episode will be marked as explicit.\n\n```yaml\nenv:\n  IS_EXPLICIT: true\n```\n\n### Sponsored Content\n\nBy setting `IS_SPONSORED`, the new episode will be marked as having promotional content (sponsored).\nDefault is `false`.\n\n```yaml\nenv:\n  IS_SPONSORED: true\n```\n\n### Thumbnail Mode\n\nBy setting the `LOAD_THUMBNAIL`, the new episode will include the video thumbnail as the episode art.\n\n```yaml\nenv:\n  LOAD_THUMBNAIL: true\n```\n\n### Add YouTube URL to Podcast Description\n\nBy setting the `URL_IN_DESCRIPTION`, the Podcast description will include the YouTube URL on a new line at the end of the description.\nIt is recommended to set it, for if the YouTube video has no description it will fail to save the new episode. Setting it to true guarantees to always have a description.\n\n```yaml\nenv:\n  URL_IN_DESCRIPTION: true\n```\n\n### Set a publish date for the episode\n\nBy setting `SET_PUBLISH_DATE`, the new episode can be scheduled for publishing the episode on the date that the YouTube video is uploaded. Please note that the scheduling will work if `SAVE_AS_DRAFT` is not set, because spotify doesn't store publish date for draft episodes.\nIf `SET_PUBLISH_DATE` is not set, then spotify will choose the current date for publishing.\n\n```yaml\nenv:\n  SET_PUBLISH_DATE: true\n```\n\n## Multiple shows per repository\n\nIt is possible to use a single repository to maintain several shows.\n\nYou'll need an episode config per show.\n\nAs an example, suppose you have two shows, you called \"Great News\" and another \"Sad News\".\n\nYou repository will look like this:\n\n```\n.github/\n├─ workflows/\n│  ├─ great-news.yaml\n│  ├─ sad-news.yaml\ngreat-news.json\nsad-news.json\n```\n\nIn `great-news.json` and `sad-news.json`, you have:\n```json\n{\n  \"id\": \"episode_video_id\"\n}\n```\n\nIn `great-news.yaml` and `sad-news.yaml`:\n```yaml\nname: 'Great News Upload Action'\non:\n  push:\n    paths:\n    ## only updates to this file trigger this action\n      - great-news.json   # or sad-news.json\njobs:\n  upload_episode:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - name: Upload Episode from YouTube To Spotify\n        uses: Schrodinger-Hat/youtube-to-spotify@v2.5.0\n        env:\n          SPOTIFY_EMAIL: ${{ secrets.SPOTIFY_EMAIL_GREATNEWS }}  # OR secrets.SPOTIFY_EMAIL_SADNEWS\n          SPOTIFY_PASSWORD: ${{ secrets.SPOTIFY_PASSWORD_GREATNEWS }}  # OR secrets.SPOTIFY_PASSWORD_SADNEWS\n          EPISODE_PATH: /github/workspace/\n          EPISODE_FILE: great-news.json\n          # (…) Other configs as needed\n```\n\n## How can I setup for development and use the script locally?\n\nTo run the script locally, you need `python3` and `ffmpeg` to be available in `PATH` which are used by the npm dependency `youtube-dl-exec`.\n\nClone the repository and run `npm ci` to install the exact dependencies that are specified in `package-lock.json`.\n\nAfter that, you can edit `episode.json` that is located at the root of this repository.\nIt is recommended to specify the id of a short YouTube video in `episode.json` for testing.\n\nThen, make sure to setup your `.env` file in the root of this repository so you can put\nthe environment variables that you normally specify in the GitHub action YAML file.\n\nTo do that, you can copy `.env.sample` into a file with name `.env`.\n\nMake sure to specify the mandatory environment variables for logging in to spotify,\n`SPOTIFY_EMAIL` and `SPOTIFY_PASSWORD`.\n\nIf needed we can set the `SPOTIFY_EMAIL` and `SPOTIFY_PASSWORD` too, so they will be used to login with the new login type after changing `SPOTIFY_LOGIN` to false.\n\nFinally, you can do `npm start` to execute the script.\n\n## How to upload a YouTube playlist to spotify using this script?\n\n⚠ WARNING: This Potentially violates GitHub's Terms of service ⚠\n\n\u003e In particular, any repositories that use GitHub Actions or similar 3rd party services solely to interact with 3rd party websites, to engage in incentivized activities, or for general computing purposes may fall foul of the [GitHub Additional Product Terms (Actions)](https://docs.github.com/github/site-policy/github-terms-for-additional-products-and-features#actions), or the [GitHub Acceptable Use Policies](https://docs.github.com/github/site-policy/github-acceptable-use-policies).\n\u003e Actions should not be used for any activity unrelated to the production, testing, deployment, or publication of the software project associated with the repository where GitHub Actions are used.\n\nCurrently, you can process a full playlist (one way only) with\n\n```bash\ncurl https://scc-youtube.vercel.app/playlist-items/PLoXdlLuaGN8ShASxcE2A4YuSto3AblDmX \\\n    | jq '.[].contentDetails.videoId' -r \\\n    | tac \\\n    | xargs -I% bash -c \"jo id='%' \u003e episode.json \u0026\u0026 git commit -am % \u0026\u0026 git push\"\n```\n\n`https://scc-youtube.vercel.app/playlist-items` is from https://github.com/ThatGuySam/youtube-json-server\n\n`jo` is a json generator https://github.com/jpmens/jo\n\n`tac` is a command present in most Linux distributions and on mac with brew install coreutils. Its from reversing the list from older to newer. Remove if you want to upload in the order presented on YouTube.\n\n`jq` is a json processor https://stedolan.github.io/jq/\n\nThis must be run on the folder where your episode.json is.\n\n# License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSchroedinger-Hat%2Fyoutube-to-spotify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSchroedinger-Hat%2Fyoutube-to-spotify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSchroedinger-Hat%2Fyoutube-to-spotify/lists"}