Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class MusicEvents(private val reactContext: ReactContext) : BroadcastReceiver()
const val PLAYBACK_METADATA = "playback-metadata-received"
const val PLAYBACK_PROGRESS_UPDATED = "playback-progress-updated"
const val PLAYBACK_ERROR = "playback-error"
const val EQUALIZER_CHANGED = "equalizer-changed"

const val EVENT_INTENT = "com.doublesymmetry.trackplayer.event"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -615,4 +615,35 @@ class MusicModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
if (verifyServiceBoundOrReject(callback)) return@launch
callback.resolve(Arguments.fromBundle(musicService.getPlayerStateBundle(musicService.state)))
}

@ReactMethod
fun getEqualizerSettings(callback: Promise) = scope.launch {
if (verifyServiceBoundOrReject(callback)) return@launch
callback.resolve(Arguments.fromBundle(musicService.getEqualizerSettings()))
}

@ReactMethod
fun setEqualizerEnabled(enabled: Boolean, callback: Promise) = scope.launch {
if (verifyServiceBoundOrReject(callback)) return@launch
musicService.setEqualizerEnabled(enabled)
callback.resolve(null)
}

@ReactMethod
fun setEqualizerPreset(preset: String, callback: Promise) = scope.launch {
if (verifyServiceBoundOrReject(callback)) return@launch
musicService.setEqualizerPreset(preset)
callback.resolve(null)
}

@ReactMethod
fun setEqualizerLevels(data: ReadableArray, callback: Promise) = scope.launch {
if (verifyServiceBoundOrReject(callback)) return@launch
val levels = ShortArray(data.size())
for (i in 0 until data.size()) {
levels[i] = data.getInt(i).toShort()
}
musicService.setEqualizerLevels(levels)
callback.resolve(null)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.doublesymmetry.trackplayer.service

import android.app.PendingIntent
import android.content.Intent
import android.content.ServiceConnection
import android.net.Uri
import android.os.Binder
import android.os.Build
Expand Down Expand Up @@ -337,6 +336,58 @@ class MusicService : HeadlessJsTaskService() {
player.prepare()
}

private fun emitEqualizerChangedEvent() {
emit(MusicEvents.EQUALIZER_CHANGED, getEqualizerSettings())
}

@MainThread
fun getEqualizerSettings(): Bundle {
return Bundle().apply{
this.putIntArray(
"bandLevels",
player.equalizer.properties.bandLevels.map { it.toInt() }.toIntArray()
)
this.putInt("bandCount", player.equalizer.numberOfBands.toInt())
this.putStringArray("presets", player.getEqualizerPresets())
val bandCount = player.equalizer.numberOfBands.toInt()
var centerBandFrequencies = Array(bandCount) {0}
for (i in 0 until bandCount) {
centerBandFrequencies[i] = player.equalizer.getCenterFreq(i.toShort())
}
this.putIntArray("centerBandFrequencies", centerBandFrequencies.toIntArray())
this.putInt("lowerBandLevelLimit", player.equalizer.bandLevelRange[0].toInt())
this.putInt("upperBandLevelLimit", player.equalizer.bandLevelRange[1].toInt())
if (player.equalizer.properties.curPreset >= 0) {
this.putString(
"activePreset",
player.equalizer.getPresetName(player.equalizer.properties.curPreset)
)
}
this.putBoolean("enabled", player.equalizer.enabled)
}
}

@MainThread
fun setEqualizerEnabled(enabled: Boolean) {
if (player.setEqualizerEnabled(enabled)) {
emitEqualizerChangedEvent()
}
}

@MainThread
fun setEqualizerPreset(name: String) {
if (player.setEqualizerPreset(name)) {
emitEqualizerChangedEvent()
}
}

@MainThread
fun setEqualizerLevels(levels: ShortArray) {
if (player.setEqualizerLevels(levels)) {
emitEqualizerChangedEvent()
}
}

@MainThread
fun getCurrentTrackIndex(): Int = player.currentIndex

Expand Down
2 changes: 2 additions & 0 deletions src/constants/Event.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export enum Event {
/** Fired when the equalizer settings have changed. */
EqualizerChanged = 'equalizer-changed',
/** Fired when the state of the player changes. */
PlaybackState = 'playback-state',
/** Fired when a playback error occurs. */
Expand Down
3 changes: 2 additions & 1 deletion src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './useActiveTrack';
export * from './usePlayWhenReady';
export * from './useEqualizer';
export * from './usePlaybackState';
export * from './usePlayWhenReady';
export * from './useProgress';
export * from './useTrackPlayerEvents';
36 changes: 36 additions & 0 deletions src/hooks/useEqualizer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useEffect, useState } from 'react';
import { Event } from '../constants';
import { EqualizerSettings } from '../interfaces';
import { addEventListener, getEqualizerSettings } from '../trackPlayer';

export const useEqualizer = (): EqualizerSettings | undefined => {
const [equalizerSettings, setEqualizerSettings] = useState<
EqualizerSettings | undefined
>();
useEffect(() => {
let mounted = true;

getEqualizerSettings()
.then((fetchedEqualizerSettings) => {
if (!mounted) return;
// Only set if it wasn't already set by the listener below:
setEqualizerSettings((currentEqualizerSettings) =>
currentEqualizerSettings ? currentEqualizerSettings : fetchedEqualizerSettings
);
})
.catch(() => {
/** only throws while you haven't yet setup, ignore failure. */
});

const sub = addEventListener(Event.EqualizerChanged, (equalizerSettings) => {
setEqualizerSettings(equalizerSettings);
});

return () => {
mounted = false;
sub.remove();
};
}, []);

return equalizerSettings;
};
12 changes: 12 additions & 0 deletions src/interfaces/EqualizerSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@


export type EqualizerSettings = {
activePreset?: string;
bandCount: number;
bandLevels: number[];
centerBandFrequencies: number[];
enabled: boolean;
lowerBandLevelLimit: number;
presets: string[];
upperBandLevelLimit: number;
}
16 changes: 9 additions & 7 deletions src/interfaces/events/EventPayloadByEvent.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import { Event } from '../../constants';

import { EqualizerSettings } from '../EqualizerSettings';
import type { PlaybackState } from '../PlaybackState';
import type { PlaybackErrorEvent } from './PlaybackErrorEvent';
import type { PlaybackQueueEndedEvent } from './PlaybackQueueEndedEvent';
import type { PlaybackTrackChangedEvent } from './PlaybackTrackChangedEvent';
import type { PlaybackActiveTrackChangedEvent } from './PlaybackActiveTrackChangedEvent';
import type { PlaybackErrorEvent } from './PlaybackErrorEvent';
import type { PlaybackMetadataReceivedEvent } from './PlaybackMetadataReceivedEvent';
import type { PlaybackPlayWhenReadyChangedEvent } from './PlaybackPlayWhenReadyChangedEvent';
import type { PlaybackProgressUpdatedEvent } from './PlaybackProgressUpdatedEvent';
import type { PlaybackQueueEndedEvent } from './PlaybackQueueEndedEvent';
import type { PlaybackTrackChangedEvent } from './PlaybackTrackChangedEvent';
import type { RemoteDuckEvent } from './RemoteDuckEvent';
import type { RemoteJumpBackwardEvent } from './RemoteJumpBackwardEvent';
import type { RemoteJumpForwardEvent } from './RemoteJumpForwardEvent';
import type { RemotePlayIdEvent } from './RemotePlayIdEvent';
import type { RemotePlaySearchEvent } from './RemotePlaySearchEvent';
import type { RemoteSkipEvent } from './RemoteSkipEvent';
import type { RemoteJumpForwardEvent } from './RemoteJumpForwardEvent';
import type { RemoteJumpBackwardEvent } from './RemoteJumpBackwardEvent';
import type { RemoteSeekEvent } from './RemoteSeekEvent';
import type { RemoteSetRatingEvent } from './RemoteSetRatingEvent';
import type { RemoteDuckEvent } from './RemoteDuckEvent';
import type { RemoteSkipEvent } from './RemoteSkipEvent';

export interface EventPayloadByEvent {
[Event.EqualizerChanged]: EqualizerSettings;
[Event.PlaybackState]: PlaybackState;
[Event.PlaybackError]: PlaybackErrorEvent;
[Event.PlaybackQueueEnded]: PlaybackQueueEndedEvent;
Expand Down
16 changes: 9 additions & 7 deletions src/interfaces/events/EventsPayloadByEvent.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import { Event } from '../../constants';

import { EqualizerSettings } from '../EqualizerSettings';
import type { PlaybackState } from '../PlaybackState';
import type { PlaybackErrorEvent } from './PlaybackErrorEvent';
import type { PlaybackQueueEndedEvent } from './PlaybackQueueEndedEvent';
import type { PlaybackTrackChangedEvent } from './PlaybackTrackChangedEvent';
import type { PlaybackActiveTrackChangedEvent } from './PlaybackActiveTrackChangedEvent';
import type { PlaybackErrorEvent } from './PlaybackErrorEvent';
import type { PlaybackMetadataReceivedEvent } from './PlaybackMetadataReceivedEvent';
import type { PlaybackPlayWhenReadyChangedEvent } from './PlaybackPlayWhenReadyChangedEvent';
import type { PlaybackProgressUpdatedEvent } from './PlaybackProgressUpdatedEvent';
import type { PlaybackQueueEndedEvent } from './PlaybackQueueEndedEvent';
import type { PlaybackTrackChangedEvent } from './PlaybackTrackChangedEvent';
import type { RemoteDuckEvent } from './RemoteDuckEvent';
import type { RemoteJumpBackwardEvent } from './RemoteJumpBackwardEvent';
import type { RemoteJumpForwardEvent } from './RemoteJumpForwardEvent';
import type { RemotePlayIdEvent } from './RemotePlayIdEvent';
import type { RemotePlaySearchEvent } from './RemotePlaySearchEvent';
import type { RemoteSkipEvent } from './RemoteSkipEvent';
import type { RemoteJumpForwardEvent } from './RemoteJumpForwardEvent';
import type { RemoteJumpBackwardEvent } from './RemoteJumpBackwardEvent';
import type { RemoteSeekEvent } from './RemoteSeekEvent';
import type { RemoteSetRatingEvent } from './RemoteSetRatingEvent';
import type { RemoteDuckEvent } from './RemoteDuckEvent';
import type { RemoteSkipEvent } from './RemoteSkipEvent';

export interface EventsPayloadByEvent {
[Event.EqualizerChanged]: EqualizerSettings & { type: Event.EqualizerChanged };
[Event.PlaybackState]: PlaybackState & { type: Event.PlaybackState };
[Event.PlaybackError]: PlaybackErrorEvent & { type: Event.PlaybackError };
[Event.PlaybackQueueEnded]: PlaybackQueueEndedEvent & {
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export * from './AndroidOptions';
export * from './EqualizerSettings';
export * from './events';
export * from './FeedbackOptions';
export * from './MetadataOptions';
export * from './NowPlayingMetadata';
Expand All @@ -10,4 +12,3 @@ export * from './ServiceHandler';
export * from './Track';
export * from './TrackMetadataBase';
export * from './UpdateOptions';
export * from './events';
21 changes: 19 additions & 2 deletions src/trackPlayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import {
DeviceEventEmitter,
NativeEventEmitter,
NativeModules,
Platform,
Platform
} from 'react-native';
// @ts-expect-error because resolveAssetSource is untyped
import { default as resolveAssetSource } from 'react-native/Libraries/Image/resolveAssetSource';

import { Event, RepeatMode, State } from './constants';
import type {
EqualizerSettings,
EventPayloadByEvent,
NowPlayingMetadata,
PlaybackState,
Expand All @@ -18,7 +19,7 @@ import type {
ServiceHandler,
Track,
TrackMetadataBase,
UpdateOptions,
UpdateOptions
} from './interfaces';

const { TrackPlayerModule: TrackPlayer } = NativeModules;
Expand Down Expand Up @@ -509,3 +510,19 @@ export async function getRepeatMode(): Promise<RepeatMode> {
export async function retry() {
return TrackPlayer.retry();
}

export async function getEqualizerSettings(): Promise<EqualizerSettings> {
return TrackPlayer.getEqualizerSettings();
}

export async function setEqualizerEnabled(enabled: boolean): Promise<void> {
return TrackPlayer.setEqualizerEnabled(enabled);
}

export async function setEqualizerPreset(preset: string): Promise<void> {
return TrackPlayer.setEqualizerPreset(preset);
}

export async function setEqualizerLevels(levels: number[]): Promise<void> {
return TrackPlayer.setEqualizerLevels(levels);
}