mirror of
https://github.com/captbaritone/webamp.git
synced 2026-08-04 07:55:28 +00:00
Un-revert, add duration to llama track
It seems the bug I saw (the demo track had an infinite duration), was not a bug in my code, but a bug/change in the latest version of mobile Safari. Undoing the revert, since it doesn't really help, and adding back the channel detection code.
This commit is contained in:
parent
5b39cb24a3
commit
373d613e19
6 changed files with 69 additions and 13 deletions
|
|
@ -65,3 +65,4 @@ export const MEDIA_TAG_REQUEST_FAILED = "MEDIA_TAG_REQUEST_FAILED";
|
|||
export const NETWORK_CONNECTED = "NETWORK_CONNECTED";
|
||||
export const NETWORK_DISCONNECTED = "NETWORK_DISCONNECTED";
|
||||
export const UPDATE_WINDOW_POSITIONS = "UPDATE_WINDOW_POSITIONS";
|
||||
export const CHANNEL_COUNT_CHANGED = "CHANNEL_COUNT_CHANGED";
|
||||
|
|
|
|||
11
js/config.js
11
js/config.js
|
|
@ -23,7 +23,16 @@ export const skinUrl = config.skinUrl === undefined ? skin : config.skinUrl;
|
|||
export const initialTracks = config.initialTracks || [
|
||||
{
|
||||
metaData: { artist: "DJ Mike Llama", title: "Llama Whippin' Intro" },
|
||||
url: llamaAudio
|
||||
url: llamaAudio,
|
||||
duration: 5.322286
|
||||
},
|
||||
{
|
||||
url: "https://cdn.changelog.com/uploads/podcast/291/the-changelog-291.mp3",
|
||||
metaData: {
|
||||
artist: "Changelog Media",
|
||||
title: "Winamp2-js with Jordan Eldredge"
|
||||
},
|
||||
duration: 4841.038367
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ function filterBreadcrumbActions(action) {
|
|||
|
||||
Raven.config(sentryDsn, {
|
||||
/* global COMMITHASH */
|
||||
release: COMMITHASH || "DEV"
|
||||
release: typeof COMMITHASH !== "undefined" ? COMMITHASH : "DEV"
|
||||
}).install();
|
||||
|
||||
// Don't prompt user to install Winamp2-js. It's probably not
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* Emulate the native <audio> element with Web Audio API */
|
||||
import { BANDS } from "../constants";
|
||||
import ElementSource from "./elementSource";
|
||||
import detectChannels from "./detectChannels";
|
||||
|
||||
export default class Media {
|
||||
constructor() {
|
||||
|
|
@ -32,10 +33,12 @@ export default class Media {
|
|||
timeupdate: function() {},
|
||||
visualizerupdate: function() {},
|
||||
ended: function() {},
|
||||
fileLoaded: function() {}
|
||||
fileLoaded: function() {},
|
||||
channelupdate: function() {}
|
||||
};
|
||||
// We don't currently know how many channels
|
||||
this._channels = null;
|
||||
this._balance = 0;
|
||||
this.name = null;
|
||||
|
||||
// The _source node has to be recreated each time it's stopped or
|
||||
// paused, so we don't create it here. Instead we create this dummy
|
||||
|
|
@ -60,6 +63,10 @@ export default class Media {
|
|||
// Create the analyser node for the visualizer
|
||||
this._analyser = this._context.createAnalyser();
|
||||
this._analyser.fftSize = 2048;
|
||||
// TODO: Tune these to something that looks like Winamp
|
||||
this._analyser.minDecibels = -90;
|
||||
this._analyser.maxDecibels = -10;
|
||||
this._analyser.smoothingTimeConstant = 0.8;
|
||||
|
||||
// Create the gain node for the volume control
|
||||
this._gainNode = this._context.createGain();
|
||||
|
|
@ -154,8 +161,29 @@ export default class Media {
|
|||
this._chanMerge.connect(this._analyser);
|
||||
|
||||
this._gainNode.connect(this._context.destination);
|
||||
window.media = this;
|
||||
}
|
||||
|
||||
_setChannels(num) {
|
||||
const assumedChannels = num == null ? 2 : num;
|
||||
this._chanSplit.disconnect();
|
||||
this._chanSplit.connect(this._leftGain, 0);
|
||||
// If we only have one channel, use it for both left and right.
|
||||
this._chanSplit.connect(this._rightGain, assumedChannels === 1 ? 0 : 1);
|
||||
this._channels = num;
|
||||
this._callbacks.channelupdate();
|
||||
}
|
||||
|
||||
_makeMono() {
|
||||
this._setChannels(1);
|
||||
}
|
||||
|
||||
_makeStereo() {
|
||||
this._setChannels(2);
|
||||
}
|
||||
_resetChannels() {
|
||||
this._setChannels(null);
|
||||
}
|
||||
/* Properties */
|
||||
duration() {
|
||||
return this._source.getDuration();
|
||||
|
|
@ -174,7 +202,7 @@ export default class Media {
|
|||
}
|
||||
|
||||
channels() {
|
||||
return this._source.getNumberOfChannels();
|
||||
return this._channels == null ? 2 : this._channels;
|
||||
}
|
||||
|
||||
sampleRate() {
|
||||
|
|
@ -182,8 +210,17 @@ export default class Media {
|
|||
}
|
||||
|
||||
/* Actions */
|
||||
play() {
|
||||
this._source.play();
|
||||
async play() {
|
||||
await this._source.play();
|
||||
if (this._channels == null) {
|
||||
detectChannels(this._staticSource)
|
||||
.then(channels => {
|
||||
this._setChannels(channels);
|
||||
})
|
||||
.catch(() => {
|
||||
this._setChannels(null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pause() {
|
||||
|
|
@ -259,10 +296,10 @@ export default class Media {
|
|||
}
|
||||
|
||||
// Used only for the initial load, since it must have a CORS header
|
||||
async loadFromUrl(url, fileName, autoPlay) {
|
||||
this.name = fileName;
|
||||
async loadFromUrl(url, autoPlay) {
|
||||
this._callbacks.waiting();
|
||||
await this._source.loadUrl(url);
|
||||
this._resetChannels();
|
||||
this._callbacks.stopWaiting();
|
||||
if (autoPlay) {
|
||||
this.play();
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ import {
|
|||
SET_EQ_OFF,
|
||||
SET_EQ_ON,
|
||||
PLAY_TRACK,
|
||||
BUFFER_TRACK
|
||||
BUFFER_TRACK,
|
||||
CHANNEL_COUNT_CHANGED
|
||||
} from "./actionTypes";
|
||||
import { next as nextTrack } from "./actionCreators";
|
||||
import { getCurrentTrackId } from "./selectors";
|
||||
|
|
@ -63,6 +64,13 @@ export default media => store => {
|
|||
});
|
||||
});
|
||||
|
||||
media.addEventListener("channelupdate", () => {
|
||||
store.dispatch({
|
||||
type: CHANNEL_COUNT_CHANGED,
|
||||
channels: media.channels()
|
||||
});
|
||||
});
|
||||
|
||||
return next => action => {
|
||||
// TODO: Consider doing this after the action, and using the state as the source of truth.
|
||||
switch (action.type) {
|
||||
|
|
@ -87,14 +95,12 @@ export default media => store => {
|
|||
case PLAY_TRACK:
|
||||
media.loadFromUrl(
|
||||
store.getState().playlist.tracks[action.id].url,
|
||||
action.name,
|
||||
true
|
||||
);
|
||||
break;
|
||||
case BUFFER_TRACK:
|
||||
media.loadFromUrl(
|
||||
store.getState().playlist.tracks[action.id].url,
|
||||
action.name,
|
||||
false
|
||||
);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ import {
|
|||
TOGGLE_SHUFFLE,
|
||||
TOGGLE_TIME_MODE,
|
||||
UPDATE_TIME_ELAPSED,
|
||||
ADD_TRACK_FROM_URL
|
||||
ADD_TRACK_FROM_URL,
|
||||
CHANNEL_COUNT_CHANGED
|
||||
} from "../actionTypes";
|
||||
|
||||
const media = (state, action) => {
|
||||
|
|
@ -44,6 +45,8 @@ const media = (state, action) => {
|
|||
case STOP:
|
||||
case IS_STOPPED:
|
||||
return { ...state, status: "STOPPED" };
|
||||
case CHANNEL_COUNT_CHANGED:
|
||||
return { ...state, channels: action.channels };
|
||||
case TOGGLE_TIME_MODE:
|
||||
const newMode = state.timeMode === "REMAINING" ? "ELAPSED" : "REMAINING";
|
||||
return { ...state, timeMode: newMode };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue