Erstellen von SoundCloud-Wellenformen in Echtzeit in React Native

Einführung

SoundCloud ist eine Musik- und Podcast-Streaming-Plattform zum Anhören von Millionen authentischer Titel. Sie haben eine wirklich interaktive Oberfläche zum Abspielen / Hören der Tracks.

Das wichtigste Merkmal in ihrer Benutzeroberfläche ist die Anzeige des Fortschritts der Spur anhand ihrer Frequenzwellenform. Dies hilft den Benutzern, die Art zu identifizieren.

Sie haben auch einen Blog-Beitrag, der beschreibt, wie die Wellenform basierend auf ihrem Bild verwendet wird. Es ist schwierig, dieselben Techniken zum Generieren der Wellenform in einer React Native- App zu verwenden. Das SDK von Waveform.js übersetzt eine Wellenform in Gleitkommazahlen, um sie auf einer HTML5-Zeichenfläche zu rendern, und ist derzeit nicht mehr betriebsbereit.

In diesem Artikel wird erläutert, wie Sie dieselbe Wellenform für unsere React Native-Apps verwenden.

Warum sollte ich SoundClouds Wellenformen verwenden?

  • Die Wellenform der SoundCloud sieht beeindruckender aus als die alte langweilige Art, den Fortschrittsbalken anzuzeigen.
  • Die vorinstallierte Wellenform gibt dem Benutzer eine Vorstellung von den verschiedenen Frequenzen, die im Song vorhanden sind.
  • Es ist auch viel einfacher, den Prozentsatz der gepufferten Spur auf einer Wellenform anzuzeigen, als ihn auf einem leeren Fortschrittsbalken anzuzeigen.

Erfahren Sie mehr über die Wellenformen von SoundCloud

Die SoundCloud bietet eine waveform_urlin ihren Tracks enthaltene API.

  • Jeder Track hat sein eigenes Unikat waveform_url.
  • Das waveform_urlenthält einen Link zu dem Bild, das über die Wolke gehisst wird.

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

Ab sofort ist jedes Argument statisch und daher in diesem aktuellen Zustand unbrauchbar. Daher müssen wir die darauf basierende Wellenform mithilfe der Container von React Native neu erstellen , um Zugriff auf die Berührungsereignisse, Stile usw. zu erhalten.

Loslegen

Hier ist eine Liste der Dinge, die Sie benötigen:

  • d3-Skala
  • d3-Array

Zunächst benötigen wir die Abtastung der Wellenform. Der Trick ist , zu ersetzen , .pngmit .jsonfür die waveform_url. Ein GETAufruf würde uns ein Antwortobjekt geben, das enthält

  • width (Breite der Wellenform)
  • Höhe (Höhe der Wellenform)
  • Samples (Array)

Weitere Informationen erhalten Sie unter folgendem Link: //w1.sndcdn.com/PP3Eb34ToNki_m.json.

Tauchen Sie ein in den Code

Fügen Sie eine benutzerdefinierte SoundCloudWave-Komponente hinzu

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

Es ist besser, eine benutzerdefinierte SoundCloudWave- Komponente zu erstellen , die je nach Bedarf an mehreren Stellen verwendet werden kann. Hier sind die erforderlichen props:

  • WaveformUrl - Das URL-Objekt zur Wellenform (Zugriff über die Tracks-API)
  • Höhe - Höhe der Wellenform
  • width - Breite der Wellenformkomponente
  • ProzentPlayable - Die Dauer der in Sekunden gepufferten Spur
  • Prozent gespielt - Die Dauer des abgespielten Titels in Sekunden
  • setTime - Der Callback-Handler zum Ändern der aktuellen Track-Zeit.

Holen Sie sich die Proben

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

Holen Sie sich die Beispiele mithilfe eines einfachen GETAPI-Aufrufs und speichern Sie das Ergebnis in der state.

Erstellen Sie eine Wellenformkomponente

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) }}>   ))}  ) }

Die Wellenformkomponente funktioniert wie folgt:

  • Die Chunks teilen das samplesObjekt basierend auf dem Objekt auf, das widthder Benutzer auf dem Bildschirm rendern möchte.
  • Die Chunks werden dann einem TouchableEreignis zugeordnet. Die Stile als width:2und height: scaleLinearHeight(mean(chunk)). Dies erzeugt die meanaus dem d3-array.
  • Das backgroundColorwird als Methode mit unterschiedlichen Parametern an die getColorMethode übergeben. Dies bestimmt dann die Farbe, die zurückgegeben werden soll, basierend auf den festgelegten Bedingungen.
  • Das Touchable onPressEreignis ruft den übergebenen benutzerdefinierten Handler auf, um die neue Suchzeit des Tracks festzulegen.

Jetzt kann diese zustandslose Komponente wie folgt in Ihre untergeordnete Komponente gerendert werden:

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

Hier ist eine der Wellenformkomponenten original und eine invertiert wie im Player der SoundCloud.

Fazit

Here are the links to the react-native-soundcloud-waveform

  • Github
  • npm

I’ve also made an app in react-native — MetalCloud for Metal Music fans where you can see the above component at work.

Here are the links:

  • IOS
  • Android

Thanks for reading. If you liked this article, show your support by clapping to share with other people on Medium.

More of the cool stuff can be found on my StackOverflow and GitHub profiles.

Follow me on LinkedIn, Medium, Twitter for further update new articles.