1677593648
An open-source Spotify, iTunes and Vox controller with TouchBar support, system-wide TouchBar controls (à la iTunes) and Spotify account integration.
Muse appends a permanent button to the control strip (right tray bar) of the TouchBar, displaying album art and playback time. You can tap it to reveal the full control bar, long press it to toggle play/pause and swipe on it to jump to next or previous track.
The app is not code signed, so after trying to open it unsuccessfully (because of GateKeeper) head to System Preferences -> Security & Privacy and manually grant it permission. At first start you'll be prompted to log into your Spotify account. It's not strictly necessary but it allows adding/removing favourites to your library.
Summon it with control + command + s You'll be greeted with an album art window in the middle of the screen, and the playback controls on your TouchBar. Pressing the hotkey one more time makes them both disappear, and they also auto-hide when you focus another application. Bring up the window and press command + q or esc to quit the app. System-wide now playing controls are also accessible from the leftmost button of the control strip, just like iTunes and Safari ones. Spotify, iTunes and Vox are currently supported. The app automatically guesses the right player to control basing on availability and playback notifications, but you can manually toggle them with the shortcuts described below.
Several handy shortcuts are provided when the popup window is open:
Keystroke | Action |
---|---|
s and space | toggle play/pause |
a and left arrow | previous track |
d and right arrow | next track |
w | focuses player window |
r | toggles repeating |
x | toggles shuffling |
l | likes track |
i | shows title |
1 | controls Spotify |
2 | controls iTunes |
3 | controls Vox |
The project is not code-signed, just clone the repository, install the pods and open the workspace file.
git clone https://github.com/xzzz9097/Muse && cd Muse/ && pod install && open Muse.xcworkspace
Author: xzzz9097
Source Code: https://github.com/xzzz9097/Muse
1677280320
This is a demo Application made using the flutter framework. this Application does not support the Spotify music streaming capability.
Diclamer - This application is just a UI Clone of Spotify which is just made for testing Flutter Framework. This application does not offer any Music Streaming Capability or does not have any Data analysis Capabilities.
The Clone is created by Ketan Aggarwal for demo purposes.
Menu Screen
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: f4abaa0735eba4dfd8f33f73363911d63931fe03
channel: stable
project_type: app
Author: ketanAggarwal58
Source code: https://github.com/ketanAggarwal58/spotifyClone-FLutter
1675731780
Spotify 2.0 with NEXT.JS (Middleware, Spotify API, Tailwind, NextAuth, Recoil)
Client
Api
To run this project, you will need to add the following environment variables to your .env file
NEXT_PUBLIC_CLIENT_SECRET
NEXT_PUBLIC_CLIENT_ID
NEXT_PUBLIC_CLIENT_SECRET
Install my-project with npm
npx create-next-app spotify_clone
cd spotify_clone
Install dependencies
Install tailwindcss and its peer dependencies via npm, and then run the init command to generate both tailwind.config.js
and postcss.config.js
.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Add the paths to all of your template files in your tailwind.config.js
file.
module.exports = {
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Add the @tailwind
directives for each of Tailwind’s layers to your ./styles/globals.css
file.
@tailwind base;
@tailwind components;
@tailwind utilities;
Install dependencies
Clone the project
git clone https://github.com/SashenJayathilaka/Spotify-Clone.git
Install dependencies This is a Next.js project bootstrapped with create-next-app
.
npm install
Start the server First, run the development server:
npm run dev
This is a Next.js project bootstrapped with create-next-app
.
Open http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying pages/index.js
. The page auto-updates as you edit the file.
API routes can be accessed on http://localhost:3000/api/hello. This endpoint can be edited in pages/api/hello.js
.
The pages/api
directory is mapped to /api/*
. Files in this directory are treated as API routes instead of React pages.
To learn more about Next.js, take a look at the following resources:
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
To deploy this project run
Deploy on Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
Your Name - @twitter_handle - sashenjayathilaka95@gmail.com
Project Link: https://github.com/SashenJayathilaka/Spotify-Clone.git
Author: SashenJayathilaka
Source code: https://github.com/SashenJayathilaka/Spotify-Clone
1667121960
Build and Deploy a Better Spotify 2.0 Clone Music App with React 18! (Tailwind, Shazam, Redux)
Master modern web development by building an improved version of Spotify. With a modern homepage, fully-fledged music player, search, lyrics, song exploration features, search, popular music around you, worldwide top charts, and much more, this is the best music application you can currently find on YouTube.
👇 Time Stamps
00:00:00 - Intro
00:06:31 - Setup
00:12:38 - Discover Section
00:23:50 - Rapid API Music Fetching
00:39:16 - Loader Component
00:40:50 - Error Component
00:41:50 - Song Card Component
00:59:48 - Play/Pause Functionality
01:05:38 - Sidebar
01:19:00 - Top Play Section
01:28:03 - Top Chart Card
01:30:57 - Top Artist - Swiper Component
01:42:50 - Song Details Page
02:12:53 - Artist Details Page
02:20:50 - Around You, Top Charts & Artists
02:36:31 - Search
2:52:48 - Deployment
Author: adrianhajdin
Source Code: https://github.com/adrianhajdin/project_music_player
1666567560
Spotify and iTunes in your menu bar
macOS MOJAVE BETA disclaimer
SpotMenu is currently NOT (entirely) compatible with Spotify on macOS MOJAVE BETA. SpotMenu will cause Spotify to crash. You can read more about how to fix it here.
SpotMenu is a combination of TrayPlay and Statusfy written entirely almost entirely in swift.
Toast: control + shift + m
Download the zip file version 1.9. Unarchive it. Run SpotMenu.app. I do not have an developer account to sign the app with therefore you will most likely receive a warning that the app is from an unidentified developer. To open the app follow these steps!
You can find all releases here.
via Homebrew Cask
brew install --cask spotmenu
First, you'll need Xcode 9. You can download this at the Mac App Store. Second, you'll need CocoaPods.
Now, use Git to clone the repository.
git clone https://github.com/kmikiy/SpotMenu.git
cd SpotMenu
pod install
Finally, open up the SpotMenu.xcworkspace. Set the "Scheme" to build the "SpotMenu" target for "My Mac". Then Product > Run (or the shortcut ⌘R).
Note:
Many thanks to @danieltmbr, @NicholasBellucci, @KamranMackey, @maurojuniorr, @Triloworld, @fabi94music, @rebdeb, @bcubic, @clinis, @Lynx901 @BatyaMedic and everyone who posted an issue / pull request
If you would like SpotMenu in your native language please translate this file and either create a Pull Request, send it to me via email or post it to this issue. I will add it to the next release of SpotMenu. Bear in mind that community will have to keep these language files up-to-date ☝🏻.
Author: Kmikiy
Source Code: https://github.com/kmikiy/SpotMenu
License: MIT license
1663994564
In this course, you'll learn:
- React functional components and their reusability
- React file and folder structure
- We'll use Redux Toolkit to manage the state of our application
- You'll achieve mastery using Tailwind and make the app responsive on all devices
- You'll learn how to fetch data from unlimited sources using RapidAPI.
Master modern web development by building an improved version of Spotify. With a modern homepage, fully-fledged music player, search, lyrics, song exploration features, search, popular music around you, worldwide top charts, and much more, this is the best music application you can currently find on YouTube.
👇 Time Stamps
00:00:00 - Intro
00:06:31 - Setup
00:12:38 - Discover Section
00:23:50 - Rapid API Music Fetching
00:39:16 - Loader Component
00:40:50 - Error Component
00:41:50 - Song Card Component
00:59:48 - Play/Pause Functionality
01:05:38 - Sidebar
01:19:00 - Top Play Section
01:28:03 - Top Chart Card
01:30:57 - Top Artist - Swiper Component
01:42:50 - Song Details Page
02:12:53 - Artist Details Page
02:20:50 - Around You, Top Charts & Artists
02:36:31 - Search
2:52:48 - Deployment
📚 Materials/References:
Starter Code: https://drive.google.com/file/d/1iTlXIZ4T3BBKjgLMsDpQn-Eux1B3ZyXO/view?usp=sharing
GitHub Code (give it a star ⭐): https://github.com/adrianhajdin/project_music_player
#spotify #react #tailwindcss #shazam #redux
1662626760
In today's post we will learn about 7 popular Node.js Spotify API Libraries.
This is a universal wrapper/client for the Spotify Web API that runs on Node.JS and the browser, using browserify/webpack/rollup.
A Node.js wrapper for Spotify's Web API.
$ npm install spotify-web-api-node --save
First, instantiate the wrapper.
var SpotifyWebApi = require('spotify-web-api-node');
// credentials are optional
var spotifyApi = new SpotifyWebApi({
clientId: 'fcecfc72172e4cd267473117a17cbd4d',
clientSecret: 'a6338157c9bb5ac9c71924cb2940e1a7',
redirectUri: 'http://www.example.com/callback'
});
If you've got an access token and want to use it for all calls, simply use the API object's set method. Handling credentials is described in detail in the Authorization section.
spotifyApi.setAccessToken('<your_access_token>');
Lastly, use the wrapper's helper methods to make the request to Spotify's Web API. The wrapper uses promises, so you need to provide a success callback as well as an error callback.
// Get Elvis' albums
spotifyApi.getArtistAlbums('43ZHCT0cAZBISjO8DG9PnE').then(
function(data) {
console.log('Artist albums', data.body);
},
function(err) {
console.error(err);
}
);
If you dont wan't to use promises, you can provide a callback method instead.
// Get Elvis' albums
spotifyApi.getArtistAlbums(
'43ZHCT0cAZBISjO8DG9PnE',
{ limit: 10, offset: 20 },
function(err, data) {
if (err) {
console.error('Something went wrong!');
} else {
console.log(data.body);
}
}
);
The functions that fetch data from the API also accept a JSON object with a set of options. For example, limit
and offset
can be used in functions that returns paginated results, such as search and retrieving an artist's albums.
Note that the options parameter is required if you're using a callback method., even if it's empty.
// Passing a callback - get Elvis' albums in range [20...29]
spotifyApi
.getArtistAlbums('43ZHCT0cAZBISjO8DG9PnE', { limit: 10, offset: 20 })
.then(
function(data) {
console.log('Album information', data.body);
},
function(err) {
console.error(err);
}
);
Spotify Downloader and alternative of Spotdl(python) tool made in NodeJS based on youtube-dl
Installation
Install from npm registry
npm install -g spotify-dl
or You can do manually
git clone https://github.com/SwapnilSoni1999/spotify-dl
cd spotify-dl
npm install
npm link
PS: You may need to type termux-setup-storage
first and allow storage permission
sh -c "$(curl -fsSL https://raw.githubusercontent.com/SwapnilSoni1999/spotify-dl/master/tools/termux.sh)"
Build docker image:
git clone https://github.com/SwapnilSoni1999/spotify-dl
cd spotify-dl
docker build -t spotify-dl .
Usage
To download highest quality audio file
spotifydl <spotify track/album/playlist link> ...
Example
$ spotifydl https://open.spotify.com/track/xyz
A complete wrapper for spotify web api for deno, node.js and the browser.
Installing the package!
npm i spotify-api.js@latest
Get your client id and client secret from here.
const Spotify = require("spotify-api.js");
const client = new Spotify.Client({ token: 'token' });
console.log(await client.tracks.get('id'));
Or create a token directly from clientID and clientSecret,
const { Client } = require("spotify-api.js");
const client = new Client({
token: { clientID: 'id', clientSecret: 'secret' },
// Ready event is required if you are providing clientID and clientSecret fields.
// As the client has to create the token first with it and then emits the ready event.
onReady() {
console.log(await client.tracks.get('id'));
}
})
// More simpler code with asynchronous operations:
const client = await Client.create({ token: { clientID: 'id', clientSecret: 'secret' } });
console.log(await client.tracks.get('id'));
A simple easy to use wrapper for the Spotify API
npm install --save node-spotify-api
Currently there are two methods available, search
and request
🔍
search
is the EASIEST way to find an artist, album, or track.
search: function({ type: 'artist OR album OR track', query: 'My search query', limit: 20 }, callback);
var Spotify = require('node-spotify-api');
var spotify = new Spotify({
id: <your spotify client id>,
secret: <your spotify client secret>
});
spotify.search({ type: 'track', query: 'All the Small Things' }, function(err, data) {
if (err) {
return console.log('Error occurred: ' + err);
}
console.log(data);
});
A very simple node.js library for the Spotify REST API
The easiest way to use node-spotify is to install it with npm: npm install spotify
Currently, there's only three (useful) methods available:
lookup: function({ type: 'artist OR album OR track', id: 'Spotify ID Hash' }, hollaback)
search: function({ type: 'artist OR album OR track', query: 'My search query', limit: 20 }, hollaback)
get: function(query, hollaback) -- See http://developer.spotify.com/en/metadata-api/overview/
Spotify WebApi for Node.js
var SpotifyModule = require('spotify-middleware-webapi');
var spotifyModule = new SpotifyModule({
"credentials": {
"clientId": "[clientId]",
"clientSecret": "[clientSecret]",
"redirect_uri": "http://localhost:3000/auth/callback"
}
});
You can use passport-spotify for auth and receive accessToken and refreshToken.
var refreshToken = [your refresh token];
spotifyModule.tokenRefresh(refreshToken, function(err, accessToken) {
//...
});
accessToken is required. refreshToken - optional. Only for update accessToken.
spotifyModule.user({
accessToken: accessToken,
refreshToken: refreshToken
}, function(err, profile, accessToken) {
// updated accessToken
});
or
spotifyModule.user({
accessToken: accessToken
}, function(err, profile, accessToken) {
// updated accessToken
});
Node.js client library for Spotify WebHelper API
API:
This module exposes the SpotifyWebHelper object, which exposes the following methods:
Example:
var nodeSpotifyWebHelper = require('node-spotify-webhelper');
var spotify = new nodeSpotifyWebHelper.SpotifyWebHelper();
// get the name of the song which is currently playing
spotify.getStatus(function (err, res) {
if (err) {
return console.error(err);
}
console.info('currently playing:',
res.track.artist_resource.name, '-',
res.track.track_resource.name);
});
Thank you for following this article.
Best Practices for APIs (Express, Node, React, Spotify API) with Ex-Apple Engineer
1659109380
Simple program to import your local music library to Spotify.
client id
and the secret
from your application's page.spotify-import -p <path to music> -c <client id> -s <secret>
Author: qarux
Source code: https://github.com/qarux/spotify-import
License:
1657542540
Utility for Spotify, even your 😼 can use Spotify now !
To install it download the latest release for your platform (OS X).
If you're a developer 💻 Clone the repo via git:
git clone https://github.com/MeoBeoI/Catify.git
And then install dependencies.
$ cd Catify && npm install
Run this two commands simultaneously in different console tabs.
$ npm run hot-server
$ npm run start-hot
or run two servers with one command
$ npm run dev
*Note: requires a node version >= 6 and an npm version >= 3
$ npm run package
Author: MeoBeoI
Source Code: https://github.com/MeoBeoI/Catify
License: MIT license
1653967907
In this tutorial, you're gonna be building the Spotify Blockchain Web3 dApp using Next.js, Solana, Phantom, QuickNode & Digital Ocean 🚀
You'll be learning about:
👉 Building the Spotify Web3 dApp with Next JS
👉 Creating your program on the Solana Blockchain using Anchor with Rust
👉 Storing your songs on the Solana blockchain
👉 Use Quicknode as our RPC provider to connect to the blockchain
👉 Use Phantom Wallet to authenticate the users
👉 Deploy this dApp to the internet using Digital Ocean
🔗 GitHub Repo: https://github.com/CleverProgrammers/spotify-clone-blockchain
#spotify #blockchain #web3 #dapp #nextjs #solana #phantom
1653906379
Learn how to add songs to your Spotify that are not on Spotify.
In this video, I will show you how to upload music to Spotify. You can upload local files to Spotify by going to the Spotify settings and enabling "Local files". Once you do so, you can navigate to the library section and click on the Local Files playlist. From there, you can add your local files to your spotify playlists.
1653425160
Los reproductores de música son dispositivos o aplicaciones que te permiten escuchar archivos de audio y grabaciones. Hay muchos reproductores de música disponibles, pero en este artículo crearemos un clon del popular servicio de transmisión de música, Spotify , utilizando React y ts-audio .
Es de esperar que este tutorial use la API de Spotify , sin embargo, Spotify y otras bases de datos de música no proporcionan un enlace o URL que se pueda transmitir en el cuerpo de su respuesta. La API de Spotify proporciona una URL de vista previa, pero la duración de las canciones está limitada a solo 30 segundos, y eso no es suficiente para nuestro ejemplo. Por lo tanto, no utilizaremos la API de Spotify ni realizaremos ninguna solicitud a ninguna API o base de datos de música.
En cambio, trabajaremos con datos ficticios que consisten en canciones y arte de imagen. Sin embargo, si se aventura a través de una API con un enlace de transmisión, también puede aplicar los métodos utilizados en este artículo. Puede encontrar el código completo de este tutorial en el repositorio de GitHub . ¡Empecemos!
ts-audio es una biblioteca agnóstica que facilita la interacción con la AudioContext
API . ts-audio le brinda métodos como reproducción, pausa y más, y le permite crear listas de reproducción. ts-audio ofrece las siguientes características:
AudioContext
APIComencemos creando una nueva aplicación React con el siguiente comando:
npx create-react-app ts-audio
Si está utilizando Yarn, ejecute el siguiente comando:
yarn create react-app ts-audio
Para el resto del tutorial, usaré Yarn. A continuación, instalamos el paquete ts-audio de la siguiente manera:
yarn add ts-audio
En esencia, ts-audio tiene dos componentes Audio
y AudioPlaylist
. Los componentes son funciones que podemos llamar con parámetros específicos.
Audio
componenteEl Audio
componente nos permite pasar una sola canción a reproducir. También nos proporciona ciertos métodos como play()
, pause()
, stop()
y más:
// App.js
import Audio from 'ts-audio';
import Lazarus from './music/Lazarus.mp3';
export default function App() {
const audio = Audio({
file: Lazarus
})
const play = () => {
audio.play()
}
const pause = () => {
audio.pause()
}
const stop = () => {
audio.stop()
}
return (
<>
<button onClick={play}>Play</button>
<button onClick={pause}>Pause</button>
<button onClick={stop}>Stop</button>
</>
)
}
En el bloque de código anterior, importamos el Audio
componente de ts-audio y la canción que queremos reproducir. Creamos una instancia de audio, la configuramos en el Audio
componente importado y luego pasamos la música importada al parámetro de archivo expuesto por el Audio
elemento.
Aprovechamos los métodos que nos proporcionó ts-audio, como play()
y pause()
, luego los pasamos a través de funciones a los botones.
AudioPlaylist
componenteEl AudioPlaylist
componente nos permite pasar múltiples canciones, pero tienen que estar en una matriz, de lo contrario, ts-audio no las reproducirá. El AudioPlaylist
componente nos proporciona métodos como play()
, pause()
, stop()
, next()
y prev()
.
El siguiente bloque de código es un ejemplo de cómo usar el AudioPlaylist
componente:
// App.js
import { AudioPlaylist } from 'ts-audio';
import Lazarus from './music/Lazarus.mp3';
import Sia from './music/Sia - Bird Set Free.mp3';
export default function App() {
const playlist = AudioPlaylist({
files: [Lazarus, Sia]
})
const play = () => {
playlist.play()
}
const pause = () => {
playlist.pause()
}
const next = () => {
playlist.next()
}
const previous = () => {
playlist.prev()
}
const stop = () => {
playlist.stop()
}
return (
<>
<button onClick={play}>Play</button>
<button onClick={pause}>Pause</button>
<button onClick={next}>Next</button>
<button onClick={prev}>Prev</button>
<button onClick={stop}>Stop</button>
</>
)
}
El reproductor de música tendrá las siguientes funcionalidades:
En la src
carpeta, cree dos carpetas llamadas images
y music
, respectivamente. Navegue a la images
carpeta y pegue las fotos que pueda necesitar. En la music
carpeta, puede pegar cualquier archivo de audio que desee usar.
En los siguientes repositorios de GitHub, puede obtener los archivos de imagen utilizados en este tutorial y obtener los archivos de audio . A continuación, importe canciones e imágenes App.js
de la siguiente manera:
import { AudioPlaylist } from 'ts-audio';
// Music import
import Eyes from './music/01. Jon Bellion - Eyes To The Sky.mp3';
import Mood from './music/24kGoldn-Mood-Official-Audio-ft.-Iann-Dior.mp3';
import Audio from './music/audio.mp3';
import Broken from './music/Cant Be Broken .mp3';
import Lazarus from './music/Lazarus.mp3';
import Sia from './music/Sia - Bird Set Free.mp3';
import Nobody from './music/T-Classic-Nobody-Fine-Pass-You.mp3';
import Yosemite from './music/Yosemite.mp3';
// Pictures import
import EyesImg from './images/Eyes to the sky.jpeg';
import MoodImg from './images/mood.jpeg';
import AudioImg from './images/lana.jpeg';
import BrokenImg from './images/lil wayne.jpeg';
import LazarusImg from './images/dave.jpeg';
import SiaImg from './images/sia.jpeg';
import NobodyImg from './images/nobody.jpeg';
import YosemiteImg from './images/travis.jpeg';
export default function App() {
const songs = [
{
title: 'Eyes to the sky',
artist: 'Jon Bellion',
img_src: EyesImg,
src: Eyes,
},
{
title: 'Lazarus',
artist: 'Dave',
img_src: LazarusImg,
src: Lazarus,
},
{
title: 'Yosemite',
artist: 'Travis scott',
img_src: YosemiteImg,
src: Yosemite,
},
{
title: 'Bird set free',
artist: 'Sia',
img_src: SiaImg,
src: Sia,
},
{
title: 'Cant be broken',
artist: 'Lil wayne',
img_src: BrokenImg,
src: Broken,
},
{
title: 'Mood',
artist: '24kGoldn',
img_src: MoodImg,
src: Mood,
},
{
title: 'Nobody fine pass you',
artist: 'T-Classic',
img_src: NobodyImg,
src: Nobody,
},
{
title: 'Dark paradise',
artist: 'Lana Del Ray',
img_src: AudioImg,
src: Audio,
},
]
const playlist = AudioPlaylist({
files: songs.map((song) => song.src),
});
const handlePlay = () => {
playlist.play();
};
const handlePause = () => {
playlist.pause();
};
const handleSkip = () => {
playlist.next();
};
const handlePrevious = () => {
playlist.prev();
};
return (
<>
<button onClick={handlePlay}>Play</button>
<button onClick={handlePause}>Pause</button>
<button onClick={handleSkip}>Next</button>
<button onClick={handlePrevious}>Prev</button>
</>
);
}
En el bloque de código anterior, importamos las canciones y las imágenes. A continuación, creamos una matriz de canciones que contiene objetos. Cada objeto tiene un title
, artist
, img_src
para las imágenes importadas y src
para las canciones importadas.
Después de eso, mapeamos a través de la matriz de canciones para llegar a la canción src
, que pasamos al parámetro de archivos. Recuerde, tenemos que pasarlo como una matriz, pero luego el map()
método crea una nueva matriz llamando a una función. Por lo tanto, podemos pasarlo al files
parámetro.
También creamos nuestros métodos y los pasamos a los distintos botones. Crearemos un Player.js
archivo para manejar los botones mientras nos ocupamos de la funcionalidad en App.js
:
// Player.js
export default function Player({ play, pause, next, prev }) {
return (
<div className="c-player--controls">
<button onClick={play}>Play</button>
<button onClick={pause}>Pause</button>
<button onClick={next}>Next</button>
<button onClick={prev}>Previous</button>
</div>
);
}
En el bloque de código de arriba, creamos un Player.js
archivo, luego capturamos los accesorios provenientes de App.js
, y finalmente los pasamos a los botones.
Para crear las funcionalidades de nuestra aplicación, importamos useState
para obtener el índice actual de la canción. Luego establecemos la imagen en la foto actual, el artista en el artista actual y el título en el título actual:
// App.js
import React, { useState } from 'react';
import Player from './Player';
import { AudioPlaylist } from 'ts-audio';
// Music import
// Pictures import
export default function App() {
const [currentSong, setCurrentSong] = useState(0);
const [isPlaying, setIsPlaying] = useState(false);
// Songs Array
const playlist =AudioPlaylist({
files: songs.map((song) => song.src),
});
const handlePlay = () => {
playlist.play();
setIsPlaying(true);
};
const handlePause = () => {
playlist.pause();
setIsPlaying(false);
};
const handleSkip = () => {
playlist.next();
setIsPlaying(true);
setCurrentSong(
(currentSong) => (currentSong + 1 + songs.length) % songs.length
);
};
const handlePrevious = () => {
playlist.prev();
setIsPlaying(true);
setCurrentSong(
(currentSong) => (currentSong - 1 + songs.length) % songs.length
);
};
return (
<>
<div className="App">
<div className="c-player">
<div className="c-player--details">
{' '}
<div className="details-img">
{' '}
<img src={songs[currentSong].img_src} alt="img" />
</div>
<h1 className="details-title">{songs[currentSong].title}</h1>
<h2 className="details-artist">{songs[currentSong].artist}</h2>
</div>
<Player
play={handlePlay}
pause={handlePause}
isPlaying={isPlaying}
setIsPlaying={setIsPlaying}
next={handleSkip}
prev={handlePrevious}
/>
</div>
</div>
</>
);
}
Creamos un evento de estado y lo pusimos a cero. Cuando hacemos clic en el botón siguiente , establecemos el estado en la suma del resto del estado actual, uno, y la duración de la canción, dividido por la duración de la canción:
currentSong + 1 + songs.length) % songs.length
Cuando hacemos clic en el botón anterior , establecemos el estado en el resto de la canción actual, menos uno, más la duración de la canción dividida por la duración de la canción:
currentSong - 1 + songs.length) % songs.length
También creamos un evento de estado que verifica si la canción se está reproduciendo o no, y luego lo pasamos como accesorios al Player
componente. Finalmente, manejamos las funcionalidades para cambiar la imagen, los artistas y el título de la canción.
Cuando iniciamos la aplicación, todo parece funcionar; las imágenes cambian al hacer clic en el botón Siguiente . Sin embargo, las canciones que se reproducen no coinciden con las imágenes y los nombres de los artistas que se muestran en la pantalla. A veces, dos o más canciones se reproducen simultáneamente.
Cuando hacemos clic en los botones siguiente o anterior , estamos recalculando los valores y provocando efectivamente una nueva representación. Para detener esto, envolvemos la matriz de canciones y la instancia creada de la lista de reproducción en un useMemo
gancho, como se ve a continuación:
// App.js
import React, { useState, useMemo } from 'react';
import Player from './Player';
import { AudioPlaylist } from 'ts-audio';
// Music import
// Pictures import
export default function App() {
const [currentSong, setCurrentSong] = useState(0);
const songs = useMemo(
() => [
{
title: 'Eyes to the sky',
artist: 'Jon Bellion',
img_src: EyesImg,
src: Eyes,
},
{
title: 'Lazarus',
artist: 'Dave',
img_src: LazarusImg,
src: Lazarus,
},
{
title: 'Yosemite',
artist: 'Travis scott',
img_src: YosemiteImg,
src: Yosemite,
},
{
title: 'Bird set free',
artist: 'Sia',
img_src: SiaImg,
src: Sia,
},
{
title: 'Cant be broken',
artist: 'Lil wayne',
img_src: BrokenImg,
src: Broken,
},
{
title: 'Mood',
artist: '24kGoldn',
img_src: MoodImg,
src: Mood,
},
{
title: 'Nobody fine pass you',
artist: 'T-Classic',
img_src: NobodyImg,
src: Nobody,
},
{
title: 'Dark paradise',
artist: 'Lana Del Ray',
img_src: AudioImg,
src: Audio,
},
],
[]
);
const playlist = useMemo(() => {
return AudioPlaylist({
files: songs.map((song) => song.src),
});
}, [songs]);
El useMemo
gancho almacena en caché el valor de manera efectiva para que no sea necesario volver a calcularlo y, por lo tanto, no provoca una nueva representación.
Usaremos íconos de Font Awesome Icons en este tutorial. Puede instalar el paquete Font Awesome usando los siguientes comandos:
yarn add @fortawesome/fontawesome-svg-core
yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/react-fontawesome
Copie y pegue el siguiente código en el Player.js
archivo:
// Player.js
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPlay, faPause, faForward, faBackward } from '@fortawesome/free-solid-svg-icons';
export default function Player({ play, pause, next, prev, isPlaying, setIsPlaying }) {
return (
<div className="c-player--controls">
<button className="skip-btn" onClick={prev}>
<FontAwesomeIcon icon={faBackward} />
</button>
<button
className="play-btn"
onClick={() => setIsPlaying(!isPlaying ? play : pause)}
>
<FontAwesomeIcon icon={isPlaying ? faPause : faPlay} />
</button>
<button className="skip-btn" onClick={next}>
<FontAwesomeIcon icon={faForward} />
</button>
</div>
);
}
En el bloque de código anterior, obtenemos los accesorios del App.js
archivo y luego los manejamos dentro del Player.js
archivo. Para diseñar, copie y pegue el siguiente código en su index.css
archivo:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Fira Sans', sans-serif;
}
body {
background-color: #ddd;
}
.App {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
max-width: 100vw;
}
.c-player {
display: block;
background-color: #0a54aa;
max-width: 400px;
display: block;
margin: 0px auto;
padding: 50px;
border-radius: 16px;
box-shadow: inset -6px -6px 12px rgba(0, 0, 0, 0.8),
inset 6px 6px 12px rgba(255, 255, 255, 0.4);
}
.c-player > h4 {
color: #fff;
font-size: 14px;
text-transform: uppercase;
font-weight: 500;
text-align: center;
}
.c-player > p {
color: #aaa;
font-size: 14px;
text-align: center;
font-weight: 600;
}
.c-player > p span {
font-weight: 400;
}
.c-player--details .details-img {
position: relative;
width: fit-content;
margin: 0 auto;
}
.c-player--details .details-img img {
display: block;
margin: 50px auto;
width: 100%;
max-width: 250px;
border-radius: 50%;
box-shadow: 6px 6px 12px rgba(0, 0, 0, 0.8),
-6px -6px 12px rgba(255, 255, 255, 0.4);
}
.c-player--details .details-img:after {
content: '';
display: block;
position: absolute;
top: -25px;
left: -25px;
right: -25px;
bottom: -25px;
border-radius: 50%;
border: 3px dashed rgb(255, 0, 0);
}
.c-player--details .details-title {
color: #eee;
font-size: 28px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8),
-2px -2px 4px rgba(255, 255, 255, 0.4);
text-align: center;
margin-bottom: 10px;
}
.c-player--details .details-artist {
color: #aaa;
font-size: 20px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8),
-2px -2px 4px rgba(255, 255, 255, 0.4);
text-align: center;
margin-bottom: 20px;
}
.c-player--controls {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 30px;
}
.c-player--controls .play-btn {
display: flex;
margin: 0 30px;
padding: 20px;
border-radius: 50%;
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.8),
-4px -4px 10px rgba(255, 255, 255, 0.4),
inset -4px -4px 10px rgba(0, 0, 0, 0.4),
inset 4px 4px 10px rgba(255, 255, 255, 0.4);
border: none;
outline: none;
background-color: #ff0000;
color: #fff;
font-size: 24px;
cursor: pointer;
}
.c-player--controls .skip-btn {
background: none;
border: none;
outline: none;
cursor: pointer;
color: rgb(77, 148, 59);
font-size: 18px;
}
En este artículo, aprendimos sobre ts-audio, una biblioteca agnóstica y fácil de usar que funciona con la AudioContext
API. Aprendimos sobre los métodos de ts-audio y cómo facilita el trabajo con archivos de audio. Finalmente, aprendimos cómo construir un reproductor de música que funcione usando ts-audio.
Fuente: https://blog.logrocket.com/build-spotify-clone-react-ts-audio/
1653424020
音楽プレーヤーは、オーディオファイルや録音を聞くことができるデバイスまたはアプリケーションです。利用できる音楽プレーヤーはたくさんありますが、この記事では、Reactとts-audioを使用して、ポピュラー音楽ストリーミングサービスであるSpotifyのクローンを作成します。
このチュートリアルではSpotifyAPIを使用することを期待するかもしれませんが、 Spotifyやその他の音楽データベースは応答本文にストリーミング可能なリンクまたはURLを提供していません。Spotify APIはプレビューURLを提供しますが、曲の長さは30秒に制限されており、この例では十分ではありません。したがって、Spotify APIを使用したり、音楽APIやデータベースにリクエストを送信したりすることはありません。
代わりに、曲とイメージアートで構成されるダミーデータを使用します。ただし、ストリーミング可能なリンクを使用してAPIに挑戦する場合は、この記事で使用されている方法を適用することもできます。このチュートリアルの完全なコードは、GitHubリポジトリにあります。始めましょう!
AudioContext
ts-audioは、 APIの操作を容易にする不可知論的なライブラリです。ts-audioは、再生、一時停止などのメソッドを提供し、プレイリストを作成できるようにします。ts-audioは次の機能を提供します。
AudioContext
ます以下のコマンドを使用して、新しいReactアプリを作成することから始めましょう。
npx create-react-app ts-audio
Yarnを使用している場合は、以下のコマンドを実行します。
yarn create react-app ts-audio
チュートリアルの残りの部分では、Yarnを使用します。次に、ts-audioパッケージを次のようにインストールします。
yarn add ts-audio
基本的に、ts-audioには2つのコンポーネントとがAudio
ありAudioPlaylist
ます。コンポーネントは、特定のパラメーターを使用して呼び出すことができる関数です。
Audio
このAudio
コンポーネントを使用すると、再生する1つの曲を渡すことができます。また、、、、などplay()
の特定のメソッドも提供します。pause()stop()
// App.js
import Audio from 'ts-audio';
import Lazarus from './music/Lazarus.mp3';
export default function App() {
const audio = Audio({
file: Lazarus
})
const play = () => {
audio.play()
}
const pause = () => {
audio.pause()
}
const stop = () => {
audio.stop()
}
return (
<>
<button onClick={play}>Play</button>
<button onClick={pause}>Pause</button>
<button onClick={stop}>Stop</button>
</>
)
}
上記のコードブロックでは、Audio
ts-audioからコンポーネントをインポートし、再生したい曲をインポートしました。オーディオインスタンスを作成し、それをインポートされたAudio
コンポーネントに設定してから、インポートされた音楽を要素によって公開されているファイルパラメーターに渡しましたAudio
。
ts-audioによって提供されたメソッドとのようなメソッドを利用し、play()
それらpause()
を関数を介してボタンに渡しました。
AudioPlaylist
このAudioPlaylist
コンポーネントを使用すると、複数の曲を渡すことができますが、それらは配列である必要があります。そうでない場合、ts-audioはそれらを再生しません。このAudioPlaylist
コンポーネントは、、、、、、などのメソッドをplay()
提供pause()
します。stop()next()prev()
以下のコードブロックは、AudioPlaylist
コンポーネントの使用方法の例です。
// App.js
import { AudioPlaylist } from 'ts-audio';
import Lazarus from './music/Lazarus.mp3';
import Sia from './music/Sia - Bird Set Free.mp3';
export default function App() {
const playlist = AudioPlaylist({
files: [Lazarus, Sia]
})
const play = () => {
playlist.play()
}
const pause = () => {
playlist.pause()
}
const next = () => {
playlist.next()
}
const previous = () => {
playlist.prev()
}
const stop = () => {
playlist.stop()
}
return (
<>
<button onClick={play}>Play</button>
<button onClick={pause}>Pause</button>
<button onClick={next}>Next</button>
<button onClick={prev}>Prev</button>
<button onClick={stop}>Stop</button>
</>
)
}
音楽プレーヤーには、次の機能があります。
フォルダに、とsrc
という2つのフォルダをそれぞれ作成します。フォルダに移動して、必要な写真を貼り付けます。フォルダには、使用したいオーディオファイルを貼り付けることができます。imagesmusicimagesmusic
次のGitHubリポジトリでは、このチュートリアルで使用されている画像ファイルを取得し、音声ファイルを取得できます。次に、曲と画像を次のようにインポートApp.js
します。
import { AudioPlaylist } from 'ts-audio';
// Music import
import Eyes from './music/01. Jon Bellion - Eyes To The Sky.mp3';
import Mood from './music/24kGoldn-Mood-Official-Audio-ft.-Iann-Dior.mp3';
import Audio from './music/audio.mp3';
import Broken from './music/Cant Be Broken .mp3';
import Lazarus from './music/Lazarus.mp3';
import Sia from './music/Sia - Bird Set Free.mp3';
import Nobody from './music/T-Classic-Nobody-Fine-Pass-You.mp3';
import Yosemite from './music/Yosemite.mp3';
// Pictures import
import EyesImg from './images/Eyes to the sky.jpeg';
import MoodImg from './images/mood.jpeg';
import AudioImg from './images/lana.jpeg';
import BrokenImg from './images/lil wayne.jpeg';
import LazarusImg from './images/dave.jpeg';
import SiaImg from './images/sia.jpeg';
import NobodyImg from './images/nobody.jpeg';
import YosemiteImg from './images/travis.jpeg';
export default function App() {
const songs = [
{
title: 'Eyes to the sky',
artist: 'Jon Bellion',
img_src: EyesImg,
src: Eyes,
},
{
title: 'Lazarus',
artist: 'Dave',
img_src: LazarusImg,
src: Lazarus,
},
{
title: 'Yosemite',
artist: 'Travis scott',
img_src: YosemiteImg,
src: Yosemite,
},
{
title: 'Bird set free',
artist: 'Sia',
img_src: SiaImg,
src: Sia,
},
{
title: 'Cant be broken',
artist: 'Lil wayne',
img_src: BrokenImg,
src: Broken,
},
{
title: 'Mood',
artist: '24kGoldn',
img_src: MoodImg,
src: Mood,
},
{
title: 'Nobody fine pass you',
artist: 'T-Classic',
img_src: NobodyImg,
src: Nobody,
},
{
title: 'Dark paradise',
artist: 'Lana Del Ray',
img_src: AudioImg,
src: Audio,
},
]
const playlist = AudioPlaylist({
files: songs.map((song) => song.src),
});
const handlePlay = () => {
playlist.play();
};
const handlePause = () => {
playlist.pause();
};
const handleSkip = () => {
playlist.next();
};
const handlePrevious = () => {
playlist.prev();
};
return (
<>
<button onClick={handlePlay}>Play</button>
<button onClick={handlePause}>Pause</button>
<button onClick={handleSkip}>Next</button>
<button onClick={handlePrevious}>Prev</button>
</>
);
}
上記のコードブロックでは、曲と画像をインポートしました。次に、オブジェクトを含む曲の配列を作成しました。各オブジェクトには、title
インポートされた画像とインポートされた曲の、があります。artistimg_srcsrc
その後、song配列を介してマッピングしsrc
、filesパラメーターに渡した曲のに到達しました。配列として渡す必要があることを忘れないでください。ただし、map()
メソッドは関数の呼び出しから新しい配列を作成します。したがって、それをfiles
パラメータに渡すことができます。
また、メソッドを作成して、さまざまなボタンに渡しました。Player.js
次の機能を処理しながら、ボタンを処理するファイルを作成しApp.js
ます。
// Player.js
export default function Player({ play, pause, next, prev }) {
return (
<div className="c-player--controls">
<button onClick={play}>Play</button>
<button onClick={pause}>Pause</button>
<button onClick={next}>Next</button>
<button onClick={prev}>Previous</button>
</div>
);
}
上記のコードブロックでは、Player.js
ファイルを作成し、からの小道具をキャッチしてApp.js
、最後にボタンに渡しました。
アプリケーションの機能を作成するために、インポートuseState
して曲の現在のインデックスを取得します。次に、画像を現在の写真に、アーティストを現在のアーティストに、タイトルを現在のタイトルに設定します。
// App.js
import React, { useState } from 'react';
import Player from './Player';
import { AudioPlaylist } from 'ts-audio';
// Music import
// Pictures import
export default function App() {
const [currentSong, setCurrentSong] = useState(0);
const [isPlaying, setIsPlaying] = useState(false);
// Songs Array
const playlist =AudioPlaylist({
files: songs.map((song) => song.src),
});
const handlePlay = () => {
playlist.play();
setIsPlaying(true);
};
const handlePause = () => {
playlist.pause();
setIsPlaying(false);
};
const handleSkip = () => {
playlist.next();
setIsPlaying(true);
setCurrentSong(
(currentSong) => (currentSong + 1 + songs.length) % songs.length
);
};
const handlePrevious = () => {
playlist.prev();
setIsPlaying(true);
setCurrentSong(
(currentSong) => (currentSong - 1 + songs.length) % songs.length
);
};
return (
<>
<div className="App">
<div className="c-player">
<div className="c-player--details">
{' '}
<div className="details-img">
{' '}
<img src={songs[currentSong].img_src} alt="img" />
</div>
<h1 className="details-title">{songs[currentSong].title}</h1>
<h2 className="details-artist">{songs[currentSong].artist}</h2>
</div>
<Player
play={handlePlay}
pause={handlePause}
isPlaying={isPlaying}
setIsPlaying={setIsPlaying}
next={handleSkip}
prev={handlePrevious}
/>
</div>
</div>
</>
);
}
状態イベントを作成し、ゼロに設定しました。[次へ]ボタンをクリックすると、状態が現在の状態の残りの1つと曲の長さの合計を、曲の長さで割った値に設定されます。
currentSong + 1 + songs.length) % songs.length
前のボタンをクリックすると、状態が現在の曲の残りの部分から1を引いた値に、曲の長さを曲の長さで割った値に設定されます。
currentSong - 1 + songs.length) % songs.length
また、曲が再生されているかどうかを確認する状態イベントを作成し、それを小道具としてPlayer
コンポーネントに渡しました。最後に、画像、アーティスト、曲名を変更する機能を処理しました。
アプリケーションを起動すると、すべてが機能しているように見えます。[次へ]ボタンをクリックすると、画像が変わります。ただし、再生中の曲は、画面に表示されている写真やアーティスト名と一致しません。2つ以上の曲が同時に再生されている場合があります。
次または前のボタンをクリックすると、値が再計算され、効果的に再レンダリングされます。これを停止するには、以下に示すように、曲の配列とプレイリストの作成されたインスタンスをuseMemo
フックでラップします。
// App.js
import React, { useState, useMemo } from 'react';
import Player from './Player';
import { AudioPlaylist } from 'ts-audio';
// Music import
// Pictures import
export default function App() {
const [currentSong, setCurrentSong] = useState(0);
const songs = useMemo(
() => [
{
title: 'Eyes to the sky',
artist: 'Jon Bellion',
img_src: EyesImg,
src: Eyes,
},
{
title: 'Lazarus',
artist: 'Dave',
img_src: LazarusImg,
src: Lazarus,
},
{
title: 'Yosemite',
artist: 'Travis scott',
img_src: YosemiteImg,
src: Yosemite,
},
{
title: 'Bird set free',
artist: 'Sia',
img_src: SiaImg,
src: Sia,
},
{
title: 'Cant be broken',
artist: 'Lil wayne',
img_src: BrokenImg,
src: Broken,
},
{
title: 'Mood',
artist: '24kGoldn',
img_src: MoodImg,
src: Mood,
},
{
title: 'Nobody fine pass you',
artist: 'T-Classic',
img_src: NobodyImg,
src: Nobody,
},
{
title: 'Dark paradise',
artist: 'Lana Del Ray',
img_src: AudioImg,
src: Audio,
},
],
[]
);
const playlist = useMemo(() => {
return AudioPlaylist({
files: songs.map((song) => song.src),
});
}, [songs]);
フックはuseMemo
値を効果的にキャッシュするため、再計算する必要がないため、再レンダリングが発生しません。
このチュートリアルでは、FontAwesomeIconsのアイコンを使用します。以下のコマンドを使用して、FontAwesomeパッケージをインストールできます。
yarn add @fortawesome/fontawesome-svg-core
yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/react-fontawesome
以下のコードをコピーしてPlayer.js
ファイルに貼り付けます。
// Player.js
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPlay, faPause, faForward, faBackward } from '@fortawesome/free-solid-svg-icons';
export default function Player({ play, pause, next, prev, isPlaying, setIsPlaying }) {
return (
<div className="c-player--controls">
<button className="skip-btn" onClick={prev}>
<FontAwesomeIcon icon={faBackward} />
</button>
<button
className="play-btn"
onClick={() => setIsPlaying(!isPlaying ? play : pause)}
>
<FontAwesomeIcon icon={isPlaying ? faPause : faPlay} />
</button>
<button className="skip-btn" onClick={next}>
<FontAwesomeIcon icon={faForward} />
</button>
</div>
);
}
上記のコードブロックでは、ファイルから小道具を取得し、App.js
ファイル内で処理しPlayer.js
ます。スタイリングについては、以下のコードをコピーしてindex.css
ファイルに貼り付けてください。
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Fira Sans', sans-serif;
}
body {
background-color: #ddd;
}
.App {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
max-width: 100vw;
}
.c-player {
display: block;
background-color: #0a54aa;
max-width: 400px;
display: block;
margin: 0px auto;
padding: 50px;
border-radius: 16px;
box-shadow: inset -6px -6px 12px rgba(0, 0, 0, 0.8),
inset 6px 6px 12px rgba(255, 255, 255, 0.4);
}
.c-player > h4 {
color: #fff;
font-size: 14px;
text-transform: uppercase;
font-weight: 500;
text-align: center;
}
.c-player > p {
color: #aaa;
font-size: 14px;
text-align: center;
font-weight: 600;
}
.c-player > p span {
font-weight: 400;
}
.c-player--details .details-img {
position: relative;
width: fit-content;
margin: 0 auto;
}
.c-player--details .details-img img {
display: block;
margin: 50px auto;
width: 100%;
max-width: 250px;
border-radius: 50%;
box-shadow: 6px 6px 12px rgba(0, 0, 0, 0.8),
-6px -6px 12px rgba(255, 255, 255, 0.4);
}
.c-player--details .details-img:after {
content: '';
display: block;
position: absolute;
top: -25px;
left: -25px;
right: -25px;
bottom: -25px;
border-radius: 50%;
border: 3px dashed rgb(255, 0, 0);
}
.c-player--details .details-title {
color: #eee;
font-size: 28px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8),
-2px -2px 4px rgba(255, 255, 255, 0.4);
text-align: center;
margin-bottom: 10px;
}
.c-player--details .details-artist {
color: #aaa;
font-size: 20px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8),
-2px -2px 4px rgba(255, 255, 255, 0.4);
text-align: center;
margin-bottom: 20px;
}
.c-player--controls {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 30px;
}
.c-player--controls .play-btn {
display: flex;
margin: 0 30px;
padding: 20px;
border-radius: 50%;
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.8),
-4px -4px 10px rgba(255, 255, 255, 0.4),
inset -4px -4px 10px rgba(0, 0, 0, 0.4),
inset 4px 4px 10px rgba(255, 255, 255, 0.4);
border: none;
outline: none;
background-color: #ff0000;
color: #fff;
font-size: 24px;
cursor: pointer;
}
.c-player--controls .skip-btn {
background: none;
border: none;
outline: none;
cursor: pointer;
color: rgb(77, 148, 59);
font-size: 18px;
}
AudioContext
この記事では、 APIで動作する不可知論者で使いやすいライブラリであるts-audioについて学習しました。ts-audioの方法と、それによってオーディオファイルの操作が簡単になる方法について学びました。最後に、ts-audioを使用して機能する音楽プレーヤーを作成する方法を学びました。
ソース:https ://blog.logrocket.com/build-spotify-clone-react-ts-audio/
1652288220
Annoy (Approximate Nearest Neighbors Oh Yeah) is a C++ library with Python bindings to search for points in space that are close to a given query point. It also creates large read-only file-based data structures that are mmapped into memory so that many processes may share the same data.
To install, simply do pip install --user annoy
to pull down the latest version from PyPI.
For the C++ version, just clone the repo and #include "annoylib.h"
.
There are some other libraries to do nearest neighbor search. Annoy is almost as fast as the fastest libraries, (see below), but there is actually another feature that really sets Annoy apart: it has the ability to use static files as indexes. In particular, this means you can share index across processes. Annoy also decouples creating indexes from loading them, so you can pass around indexes as files and map them into memory quickly. Another nice thing of Annoy is that it tries to minimize memory footprint so the indexes are quite small.
Why is this useful? If you want to find nearest neighbors and you have many CPU's, you only need to build the index once. You can also pass around and distribute static files to use in production environment, in Hadoop jobs, etc. Any process will be able to load (mmap) the index into memory and will be able to do lookups immediately.
We use it at Spotify for music recommendations. After running matrix factorization algorithms, every user/item can be represented as a vector in f-dimensional space. This library helps us search for similar users/items. We have many millions of tracks in a high-dimensional space, so memory usage is a prime concern.
Annoy was built by Erik Bernhardsson in a couple of afternoons during Hack Week.
from annoy import AnnoyIndex
import random
f = 40
t = AnnoyIndex(f, 'angular') # Length of item vector that will be indexed
for i in range(1000):
v = [random.gauss(0, 1) for z in range(f)]
t.add_item(i, v)
t.build(10) # 10 trees
t.save('test.ann')
# ...
u = AnnoyIndex(f, 'angular')
u.load('test.ann') # super fast, will just mmap the file
print(u.get_nns_by_item(0, 1000)) # will find the 1000 nearest neighbors
Right now it only accepts integers as identifiers for items. Note that it will allocate memory for max(id)+1 items because it assumes your items are numbered 0 … n-1. If you need other id's, you will have to keep track of a map yourself.
AnnoyIndex(f, metric)
returns a new index that's read-write and stores vector of f
dimensions. Metric can be "angular"
, "euclidean"
, "manhattan"
, "hamming"
, or "dot"
.a.add_item(i, v)
adds item i
(any nonnegative integer) with vector v
. Note that it will allocate memory for max(i)+1
items.a.build(n_trees, n_jobs=-1)
builds a forest of n_trees
trees. More trees gives higher precision when querying. After calling build
, no more items can be added. n_jobs
specifies the number of threads used to build the trees. n_jobs=-1
uses all available CPU cores.a.save(fn, prefault=False)
saves the index to disk and loads it (see next function). After saving, no more items can be added.a.load(fn, prefault=False)
loads (mmaps) an index from disk. If prefault is set to True, it will pre-read the entire file into memory (using mmap with MAP_POPULATE). Default is False.a.unload()
unloads.a.get_nns_by_item(i, n, search_k=-1, include_distances=False)
returns the n
closest items. During the query it will inspect up to search_k
nodes which defaults to n_trees * n
if not provided. search_k
gives you a run-time tradeoff between better accuracy and speed. If you set include_distances
to True
, it will return a 2 element tuple with two lists in it: the second one containing all corresponding distances.a.get_nns_by_vector(v, n, search_k=-1, include_distances=False)
same but query by vector v
.a.get_item_vector(i)
returns the vector for item i
that was previously added.a.get_distance(i, j)
returns the distance between items i
and j
. NOTE: this used to return the squared distance, but has been changed as of Aug 2016.a.get_n_items()
returns the number of items in the index.a.get_n_trees()
returns the number of trees in the index.a.on_disk_build(fn)
prepares annoy to build the index in the specified file instead of RAM (execute before adding items, no need to save after build)a.set_seed(seed)
will initialize the random number generator with the given seed. Only used for building up the tree, i. e. only necessary to pass this before adding the items. Will have no effect after calling a.build(n_trees) or a.load(fn).Notes:
sqrt(2(1-cos(u,v)))
The C++ API is very similar: just #include "annoylib.h"
to get access to it.
There are just two main parameters needed to tune Annoy: the number of trees n_trees
and the number of nodes to inspect during searching search_k
.
n_trees
is provided during build time and affects the build time and the index size. A larger value will give more accurate results, but larger indexes.search_k
is provided in runtime and affects the search performance. A larger value will give more accurate results, but will take longer time to return.If search_k
is not provided, it will default to n * n_trees
where n
is the number of approximate nearest neighbors. Otherwise, search_k
and n_trees
are roughly independent, i.e. the value of n_trees
will not affect search time if search_k
is held constant and vice versa. Basically it's recommended to set n_trees
as large as possible given the amount of memory you can afford, and it's recommended to set search_k
as large as possible given the time constraints you have for the queries.
You can also accept slower search times in favour of reduced loading times, memory usage, and disk IO. On supported platforms the index is prefaulted during load
and save
, causing the file to be pre-emptively read from disk into memory. If you set prefault
to False
, pages of the mmapped index are instead read from disk and cached in memory on-demand, as necessary for a search to complete. This can significantly increase early search times but may be better suited for systems with low memory compared to index size, when few queries are executed against a loaded index, and/or when large areas of the index are unlikely to be relevant to search queries.
Using random projections and by building up a tree. At every intermediate node in the tree, a random hyperplane is chosen, which divides the space into two subspaces. This hyperplane is chosen by sampling two points from the subset and taking the hyperplane equidistant from them.
We do this k times so that we get a forest of trees. k has to be tuned to your need, by looking at what tradeoff you have between precision and performance.
Hamming distance (contributed by Martin Aumüller) packs the data into 64-bit integers under the hood and uses built-in bit count primitives so it could be quite fast. All splits are axis-aligned.
Dot Product distance (contributed by Peter Sobot) reduces the provided vectors from dot (or "inner-product") space to a more query-friendly cosine space using a method by Bachrach et al., at Microsoft Research, published in 2014.
It's all written in C++ with a handful of ugly optimizations for performance and memory usage. You have been warned :)
The code should support Windows, thanks to Qiang Kou and Timothy Riley.
To run the tests, execute python setup.py nosetests. The test suite includes a big real world dataset that is downloaded from the internet, so it will take a few minutes to execute.
Feel free to post any questions or comments to the annoy-user group. I'm @fulhack on Twitter.
Author: spotify
Source Code: https://github.com/spotify/annoy
License: Apache-2.0 License
1649045040
Drip - A YouTube Music Client
A simple YouTube Music Client written in Dart using Flutter Framework with @microsoft Fluent design guidlines.
Dark Theme
Light Theme
Big thanks to the following people for their awesome Open Source projects. Learnt a lot from their projects. Really great work.
UI / UX improvements @wantedbear007
Author: Spsden
Source Code: https://github.com/Spsden/Drip
License: GPL-3.0 License