Untitled
unknown
typescript
2 years ago
5.5 kB
7
Indexable
import getConfig from 'next/config';
import axios from 'axios';
import jsonpAdapter from 'axios-jsonp';
import { Howl } from 'howler';
import { addActiveSound, removeActiveSound } from '../../redux/slices/audioController';
const { publicRuntimeConfig } = getConfig();
type SourceType = {
name: string;
id: string | null;
};
type TrackType = {
name: string;
src: string;
link: string;
id: string;
howl: Howl;
};
export function getPlayer(albumId, source, callbackWhenLoaded) {
let player = new Player(
{
name: source,
id: albumId,
},
callbackWhenLoaded
);
return player;
}
class Player {
src: SourceType;
callbackWhenLoaded: Function;
tracks: TrackType[];
index: number;
url: string;
loaded: boolean;
playing: boolean;
data: Object;
constructor(src: SourceType, callbackWhenLoaded: Function) {
this.src = {
name: src.name,
id: src.id,
};
this.callbackWhenLoaded = callbackWhenLoaded;
this.tracks = [];
this.index = 0;
this.url = null;
this.loaded = false;
this.playing = false;
this.data = null;
this.init();
}
init() {
if (this.src.name == 'Deezer') {
this.runDeezer();
} else if (this.src.name == 'FeedFm') {
this.runFeedFm();
}
}
runDeezer() {
this.url = `https://api.deezer.com/album/${this.src.id}?output=jsonp`;
axios
.get(this.url, { adapter: jsonpAdapter })
.then((res) => {
let data = res.data;
data.tracks.data.forEach((item, i) => {
this.tracks[i] = {
name: item.title,
src: item.preview,
link: item.link,
id: item.id,
howl: null,
};
});
})
.then(() => {
this.data = {
tracks: this.tracks,
};
this.loaded = true;
this.getSound(0);
this.callbackWhenLoaded(true);
})
.catch((error) => {
console.error(error);
});
}
runFeedFm() {
const token = publicRuntimeConfig.FEEDFM_CLIENT_TOKEN;
const secret = publicRuntimeConfig.FEEDFM_CLIENT_SECRET;
const encodedBase64Token = Buffer.from(`${token}:${secret}`).toString('base64');
const authorization = `Basic ${encodedBase64Token}`;
const getSessionUrl = `https://feed.fm/api/v2/session`;
axios
.post(getSessionUrl, {}, { headers: { Authorization: authorization } })
.then((res) => {
const clientId = res.data.session.client_id;
const placementId = res.data.placement.id;
const getSessionUrl = `https://feed.fm/api/v2/station/13586077/audio_file`;
axios
.get(getSessionUrl, {
headers: { Authorization: authorization },
params: { client_id: clientId },
})
.then((res) => {
let data = res.data;
data.audio_files.forEach((item, i) => {
let getAudioFileUrl = `https://feed.fm/api/v2/play`;
axios
.post(
getAudioFileUrl,
{},
{
headers: { Authorization: authorization },
params: { client_id: clientId, placement_id: placementId, audio_file_id: item.id },
}
)
.then((res) => {
let data = res.data.play.audio_file;
this.tracks[i] = {
name: data.track.title,
src: data.url,
link: data.url,
id: data.track.id,
howl: null,
};
})
.catch((error) => {
console.error(error);
});
});
})
.then(() => {
this.data = {
tracks: this.tracks,
};
this.loaded = true;
this.getSound(0);
this.callbackWhenLoaded(true);
})
.catch((error) => {
console.error(error);
});
})
.catch((error) => {
console.error(error);
});
}
getSound(index = 0) {
let sound;
index = typeof index === 'number' ? index : this.index;
let data = this.tracks[index];
if (data) {
if (data.howl) {
sound = data.howl;
} else {
sound = data.howl = new Howl({
src: data.src,
html5: true,
});
sound.on('play', addActiveSound(this.tracks[index].name, sound, 2));
sound.on('end', () => {
removeActiveSound(this.tracks[index].name)();
this.skip('next');
});
}
this.index = index;
return sound;
}
}
play(index) {
let sound = this.getSound(index);
sound.play();
}
skip(direction) {
let index = 0;
if (direction === 'prev') {
index = this.index - 1;
if (index < 0) {
index = this.tracks.length - 1;
}
} else {
index = this.index + 1;
if (index >= this.tracks.length) {
index = 0;
}
}
this.skipTo(index);
}
skipTo(index) {
if (this.tracks[this.index] && this.tracks[this.index].howl) {
this.tracks[this.index].howl.stop();
}
this.play(index);
}
}
Editor is loading...