Sådan oprettes SoundCloud Waveforms i realtid i React Native

Introduktion

SoundCloud er en platform til streaming af musik og podcast til at lytte til millioner af autentiske spor. De har en virkelig interaktiv grænseflade til afspilning / lytning til sporene.

Den vigtigste funktion i deres grænseflade viser sporets forløb baseret på dets frekvensbølgeform. Dette hjælper brugerne med at identificere arten af ​​det.

De har også et blogindlæg, der beskriver, hvordan man bruger bølgeformen baseret på dets billede. Det er svært at bruge de samme teknikker til at generere bølgeformen i en React Native- app. Deres Waveform.js SDK oversætter en bølgeform til flydende punkter for at gengive på et HTML5-lærred og er i øjeblikket ikke længere i drift.

I denne artikel diskuterer vi, hvordan du bruger den samme bølgeform til vores React Native-apps.

Hvorfor skal jeg bruge SoundClouds bølgeformer?

  • SoundClouds bølgeform ser mere imponerende ud end den gamle kedelige måde at vise statuslinjen på.
  • Den forudindlæste bølgeform giver brugeren en idé om de forskellige frekvenser, der findes i sangen.
  • Det er også meget lettere at vise den pufrede sporprocent på en bølgeform i stedet for at vise den på en tom statuslinje.

Lad os lære mere om SoundClouds Waveforms

SoundCloud giver en waveform_urli sine spor API.

  • Hvert spor har sin egen unikke waveform_url.
  • Den waveform_urlindeholder et link til billedet hejst over skyen.

Eksempel - //w1.sndcdn.com/PP3Eb34ToNki_m.png

Fra nu af er ethvert argument statisk, og derfor er det ubrugeligt i denne nuværende tilstand. Derfor er vi nødt til at genskabe bølgeformen baseret på den ved hjælp af React Native's containere for at få adgang til berøringshændelser, stilarter osv.

Kom godt i gang

Her er en liste over ting, du har brug for:

  • d3-skala
  • d3-array

For det første har vi brug for prøveudtagning af bølgeformen. Tricket er at erstatte .pngmed .jsonfor waveform_url. Et GETkald til det ville give os et svarobjekt, der indeholder

  • bredde (bredde af bølgeformen)
  • højde (bølgeformens højde )
  • prøver (Array)

For mere info kan du prøve følgende link //w1.sndcdn.com/PP3Eb34ToNki_m.json.

Dyk ned i koden

Tilføj en brugerdefineret SoundCloudWave-komponent

function percentPlayed (time, totalDuration) { return Number(time) / (Number(totalDuration) / 1000)}

Det ville være bedre at oprette en brugerdefineret SoundCloudWave- komponent, der kan bruges flere steder efter behov. Her er de krævede props:

  • waveformUrl - URL-objektet til bølgeformen (tilgængelig via Tracks API)
  • højde - Bølgeformens højde
  • bredde - Bredde på bølgeformkomponenten
  • percentPlayable - Varigheden af ​​sporet bufret i sekunder
  • percentPlayed - Varigheden af ​​det nummer, der spilles i sekunder
  • setTime - tilbagekaldshåndtereren for at ændre den aktuelle sporetid.

Få prøverne

fetch(waveformUrl.replace('png', 'json')) .then(res => res.json()) .then(json => { this.setState({ waveform: json, waveformUrl }) });

Få prøverne ved hjælp af et simpelt GETAPI-opkald, og gem resultatet i state.

Opret en kurvekomponent

import { mean } from 'd3-array';
const ACTIVE = '#FF1844', INACTIVE = '#424056', ACTIVE_PLAYABLE = '#1b1b26'
const ACTIVE_INVERSE = '#4F1224', ACTIVE_PLAYABLE_INVERSE = '#131116', INACTIVE_INVERSE = '#1C1A27'
function getColor( bars, bar, percentPlayed, percentPlayable, inverse) { if(bar/bars.length < percentPlayed) { return inverse ? ACTIVE : ACTIVE_INVERSE } else if(bar/bars.length < percentPlayable) { return inverse ? ACTIVE_PLAYABLE : ACTIVE_PLAYABLE_INVERSE } else { return inverse ? INACTIVE : INACTIVE_INVERSE }}
const Waveform = ( { waveform, height, width, setTime, percentPlayed, percentPlayable, inverse } ) => { const scaleLinearHeight = scaleLinear().domain([0, waveform.height]).range([0, height]); const chunks = _.chunk(waveform.samples, waveform.width/((width - 60)/3)) return (  {chunks.map((chunk, i) => (  { setTime(i) }}>   ))}  ) }

Den kurve Component fungerer således:

  • Chunks delte samplesobjektet ud fra det width, som brugeren ønsker at gengive på skærmen.
  • Stykkerne kortlægges derefter til en Touchablebegivenhed. Stilene som width:2og height: scaleLinearHeight(mean(chunk)). Dette genererer meanfra d3-array.
  • Den backgroundColorsendes som en metode med forskellige parametre end getColormetoden. Dette bestemmer derefter farven, der skal returneres, baseret på de indstillede betingelser.
  • Den Touchable onPressbegivenhed vil kalde den brugerdefinerede handleren gået ind i det, for at indstille den nye søgetid af sporet.

Nu kan denne statsløse komponent gengives til din underordnede komponent som:

render() { const {height, width} = this.props const { waveform } = this.state if (!waveform) return null; return (     )}

Her er en af ​​bølgeformkomponenterne original og en inverteret som i SoundClouds afspiller.

Konklusion

Her er linkene til den reaktive-native-soundcloud-bølgeform

  • Github
  • npm

Jeg har også lavet en app i react-native - MetalCloud til Metal Music-fans, hvor du kan se ovenstående komponent på arbejde.

Her er linkene:

  • IOS
  • Android

Tak for læsningen. Hvis du kunne lide denne artikel, skal du vise din støtte ved at klappe for at dele med andre på Medium.

Flere af de seje ting kan findes på mine StackOverflow- og GitHub-profiler.

Følg mig på LinkedIn, Medium, Twitter for yderligere opdatering af nye artikler.