Skip to content
Animesh edited this page Dec 10, 2024 · 28 revisions

Welcome to the ytify wiki!

The workings of the entire project will be documented here for future contributors & maintainers.

Building

  • Since this is a Node.js Project, npm run build will build the project aided by Vite and the Typescript Compiler.

Local Development

- player: {
    proxy: string 
}
- api: {
    piped: string[],
    invidious: string[],
    hyperpipe: string,
    unified: number // no of instances with same piped & invidious domain
  },
- downloadAPI: string // Cobalt API

API handling

https://github.com/n-ce/ytify/blob/da64e12d97f38b13b74e9597332347d28ffa7722/src/modules/start.ts#L11-L27

The Piped API is used in retrieving

  • Search Results /search?q={}&f={}
  • Playlist/Channel Data /playlist/:id & /channel/:id
  • Mixes (Radio) /playlist/RD+:id
  • Playback Data /streams/:id

The Invidious API is used in retriving

  • Sorted Search Results by Time/Views /api/v1/search?q={}&sort={}&page={}
  • Playback Data (Fallback over Piped) /api/v1/videos/:id

The HyperPipe API is used in retrieving

  • YT Music Artist Data /channel/:id

Playback

https://github.com/n-ce/ytify/blob/main/src/lib/player.ts

Audio Events

https://github.com/n-ce/ytify/blob/main/src/scripts/audioEvents.ts

Library

Database Overview

{
"collection1":{},
"collection2":{},
/* ........., */
"history":{},
"discover":{},
"favorites":{},
"listenLater":{},
"channels":{},
"playlists":{},
}
  • Collections are renamable/deletable, while rest are known as reserved collections which cannot be deleted or renamable.
"MyCollection" : {
"id1:string":{
"id1":string, // 11 letter yt stream id
"title":string,
"duration":string, // 'HH?:MM:SS' reduces computation
"channelUrl":string // /channel/:channelId
},
"id2:string":{
"id2":string, // 11 letter yt stream id
"title":string,
"duration":string, // 'HH?:MM:SS' reduces computation
"channelUrl":string // /channel/:channelId
},
/* ... */
}
  • history, favorites, discover, listenLater follow the same schema as other collections with the exception of discover having an extra frequency number field which keeps track of how many times it has appeared in recommendedVideos.
  • channels & playlists are informally known as super collections since they contain collection of collections in a way.
"channels":{
"id":string,
"name":string,
"thumbnail":string // thumbnail id starting with a '/'
},
"playlists":{
"id":string,
"name":string,
"thumbnail":string, // thumbnail id starting with a '/'
"uploader":string
}
  • albums are special items in playlists with a name starting with 'Album - '. That is how the Piped API defines them.
  • artists are special items in channels with a name starting with 'Artist - ', this text however is prepended via ytify itself.

Queue

https://github.com/n-ce/ytify/blob/main/src/scripts/queue.ts

Instances

  • ytify started by scraping of streaming download links from a now discontinued youtube downloader.

  • I developed a yt-dlp backend for the same purpose for v5, which has now been discontinued in favor of

  • the piped api in v5.1 release, had been using so without any changes

  • until like september of 2023 when the piped api underwent some changes (due to yt) that affected playback which could only be solvable by implementing dash playback. To me this was a major change, I somehow luckily stumbled upon the invidious api so i started using it just for streams (v6.5), leaving search and other api operations to piped as is.

  • After sometime I learnt that some hosts have both piped and invidious instances, somehow had the idea to reimplement the streams with piped but switch the playback links with their invidious counterpart (v6.9, April 2024), this actually worked and we have kept that architechture intact so far, AKA the Unified Instance Architechture.

  • Starting July 2024, the instances list is being maintained by Uma

  • In September 2024 due to ongoing YT bans, the Unified Instance Architechture was deprecated in favor of Dynamic Instance Architechture which prioritizes data fetching over unification but is still built on top of the unified base list, and the list continues to be maintained by Uma.

  • By the end of November 2024, a fallback unofficial instance was added along with an emergency mode (using download link to play, talk about coming full circle), this hybrid approach of [unified instances x dynamic instances x fallback instance x emergency mode] was perfected by the first week of December ensuring playback.

Icons

To modify icons in the project, one has to first sync with the full icon base by

  • Visiting https://remixicon.com/collection
  • Press Back to go to https://remixicon.com
  • Start Searching & Selecting all icons from the remixicon.css file.
  • When you are done, go back to the /collection by pressing Forward.
  • Now Press on Download Fonts Button which will download a zip.
  • Extract only the remixicon.css and remixicon.woff2 files.
  • Now you can replace them with the original files in the project.

Featured Playlists

Dataset / Raw

Outline

  • It uses a basic txt formatting not json for efficiency.
  • A new playlist data appears after every blank line.
  • Each data item is separated by a line.
  • The first item is playlist name.
  • The second item is playlist id.
  • The third item is playlist thumbnail id.

How to add your own playlist

  1. Visit your desired ytm site, Beatbump recommended.
  2. Search your desired playlist and open it.
  3. Get the playlist id from the link of the playlist.
  4. Get the thumbnail id from the image link of the thumbnail.
  5. Add to the database by following the outline above.

Develop

Here's an example implementation in js that converts the text to array to an array of objects.

fetch('https://raw.githubusercontent.com/wiki/n-ce/ytify/ytm_pls.md')
    .then(res => res.text())
    .then(text => text.split('\n'))
    .then(data => {
      const array = [];
      for (let i = 0; i < data.length; i += 4)
        array.push({
          "type": "playlist",
          "name": data[i + 1],
          "uploaderName": "YouTube Music",
          "url": '/playlists/' + data[i + 2],
          "thumbnail": '/' + data[i + 3]
        });
       // do whatever with array
    });

More...

Clone this wiki locally