Giter Site home page Giter Site logo

naomiaro / waveform-playlist Goto Github PK

View Code? Open in Web Editor NEW
1.4K 64.0 282.0 38.34 MB

Multitrack Web Audio editor and player with canvas waveform preview. Set cues, fades and shift multiple tracks in time. Record audio tracks or provide audio annotations. Export your mix to AudioBuffer or WAV! Add effects from Tone.js. Project inspired by Audacity.

Home Page: https://naomiaro.github.io/waveform-playlist/

License: MIT License

HTML 16.35% JavaScript 75.82% SCSS 7.84%
playlist waveform audio audio-visualizer audio-player annotations audiorecorder webaudio music mediarecorder

waveform-playlist's Introduction

npm

Sponsors

Become a sponsor

Waveform Playlist

Inspired by Audacity, this project is a multiple track playlist editor written in ES2015 using the Web Audio API.

Load tracks and set cues (track cue in, cue out), fades (track fade in, fade out) and track start/end times within the playlist. I've written up some demos on github for the different audio fade types in the project.

Screenshot (code for picture shown can be found in ghpages/_examples/04stemtracks.html)

Screenshot (code for picture shown can be found in ghpages/_examples/13annotations.html)

Browser Support

Waveform Playlist requires webaudio in the browser to function correctly: Can I Use?

Installation

npm install waveform-playlist --save

Hate npm? Check Unpkg: https://unpkg.com/browse/waveform-playlist/

  • If you want to download and run the already compiled website, navigate to folder /dist and run python -m SimpleHTTPServer 8000. The website will be available at localhost:8000/waveform-playlist.

Basic Usage

https://github.com/naomiaro/waveform-playlist/blob/main/examples/basic-html/

https://github.com/naomiaro/waveform-playlist/tree/main/examples/basic-express/

import WaveformPlaylist from "waveform-playlist";

var playlist = WaveformPlaylist({
  samplesPerPixel: 3000,
  mono: true,
  waveHeight: 70,
  container: document.getElementById("playlist"),
  state: "cursor",
  colors: {
    waveOutlineColor: "#E0EFF1",
    timeColor: "grey",
    fadeColor: "black",
  },
  controls: {
    show: false,
    width: 150,
  },
  zoomLevels: [500, 1000, 3000, 5000],
});

playlist
  .load([
    {
      src: "media/audio/Vocals30.mp3",
      name: "Vocals",
      gain: 0.5,
    },
    {
      src: "media/audio/BassDrums30.mp3",
      name: "Drums",
      start: 8.5,
      fadeIn: {
        duration: 0.5,
      },
      fadeOut: {
        shape: "logarithmic",
        duration: 0.5,
      },
    },
    {
      src: "media/audio/Guitar30.mp3",
      name: "Guitar",
      start: 23.5,
      fadeOut: {
        shape: "linear",
        duration: 0.5,
      },
      cuein: 15,
    },
  ])
  .then(function () {
    // can do stuff with the playlist.
  });

Playlist Options

var options = {
  // webaudio api AudioContext
  ac: new (window.AudioContext || window.webkitAudioContext)(),

  // DOM container element REQUIRED
  container: document.getElementById("playlist"),

  // sample rate of the project. (used for correct peaks rendering)
  sampleRate: new (
    window.AudioContext || window.webkitAudioContext
  ).sampleRate(),

  // number of audio samples per waveform peak.
  // must be an entry in option: zoomLevels.
  samplesPerPixel: 4096,

  // whether to draw multiple channels or combine them.
  mono: true,

  // enables "exclusive solo" where solo switches between tracks
  exclSolo: false,

  // default fade curve type.
  fadeType: "logarithmic", // (logarithmic | linear | sCurve | exponential)

  // whether or not to include the time measure.
  timescale: false,

  // control panel on left side of waveform
  controls: {
    // whether or not to include the track controls
    show: false,

    // width of controls in pixels
    width: 150,

    // whether to render the widget or not in the controls panel.
    widgets: {
      // Mute & solo button widget
      muteOrSolo: true,

      // Volume slider
      volume: true,

      // Stereo pan slider
      stereoPan: true,

      // Collapse track button
      collapse: true,

      // Remove track button
      remove: true,
    },
  },

  colors: {
    // color of the wave background
    waveOutlineColor: "white",

    // color of the time ticks on the canvas
    timeColor: "grey",

    // color of the fade drawn on canvas
    fadeColor: "black",
  },

  // height in pixels of each canvas element a waveform is on.
  waveHeight: 128,

  // width in pixels of waveform bars.
  barWidth: 1,

  // spacing in pixels between waveform bars.
  barGap: 0,

  // interaction state of the playlist
  // (cursor | select | fadein | fadeout | shift)
  state: "cursor",

  // (line | fill)
  seekStyle: "line",

  // Array of zoom levels in samples per pixel.
  // Smaller numbers have a greater zoom in.
  zoomLevels: [512, 1024, 2048, 4096],

  // Whether to automatically scroll the waveform while playing
  isAutomaticScroll: false,

  // configuration object for the annotations add on.
  annotationList: {
    // Array of annotations in [Aeneas](https://github.com/readbeyond/aeneas) JSON format
    annotations: [],

    // Whether the annotation texts will be in updateable contenteditable html elements
    editable: false,

    // User defined functions which can manipulate the loaded annotations
    controls: [
      {
        // class names for generated <i> tag separated by '.'
        class: "fa.fa-minus",

        // title attribute for the generated <i> tag
        title: "Reduce annotation end by 0.010s",

        // function which acts on the given annotation row
        // when the corresponding <i> is clicked.
        action: (annotation, i, annotations, opts) => {
          // @param Object annotation - current annotation
          // @param Number i - index of annotation
          // @param Array annotations - array of annotations in the playlist
          // @param Object opts - configuration options available
          //      - opts.linkEndpoints
        },
      },
    ],

    // If false when clicking an annotation id segment
    // playback will stop after segment completion.
    isContinuousPlay: false,

    // If true annotation endpoints will remain linked when dragged
    // if they were the same value before dragging started.
    linkEndpoints: false,

    // pass a custom function which will receive the mastergainnode for this playlist and the audio context's destination.
    // if you pass a function, you must connect these two nodes to hear sound at minimum.
    // if you need to clean something up when the graph is disposed, return a cleanup function. Waveform Playlist will cleanup the nodes passed as arguments.
    effects: function (masterGainNode, destination, isOffline) {
      // analyser nodes don't work offline.
      if (!isOffline) masterGainNode.connect(analyser);
      masterGainNode.connect(destination);

      // return function cleanup() {
      //   // if you create webaudio nodes that need to be cleaned up do that here
      //   // see the track effects example.
      // };
    },
  },
};

Track Options

{
  // a media path for XHR, a Blob, a File, or an AudioBuffer object.
  src: 'media/audio/BassDrums30.mp3',

  // name that will display in the playlist control panel.
  name: 'Drums',

  // volume level of the track between [0-1]
  gain: 1,

  // whether the track should initially be muted.
  muted: false,

  // whether the track should initially be soloed.
  soloed: false,

  // time in seconds relative to the playlist
  // ex (track will start after 8.5 seconds)
  // DEFAULT 0 - track starts at beginning of playlist
  start: 8.5,

  // track fade in details
  fadeIn: {
    // fade curve shape
    // (logarithmic | linear | sCurve | exponential)
    shape: 'logarithmic',

    // length of fade starting from the beginning of this track, in seconds.
    duration: 0.5,
  },

  // track fade out details
  fadeOut: {
    // fade curve shape
    // (logarithmic | linear | sCurve | exponential)
    shape: 'logarithmic',

    //length of fade which reaches the end of this track, in seconds.
    duration: 0.5,
  }

  // where the waveform for this track should begin from
  // ex (Waveform will begin 15 seconds into this track)
  // DEFAULT start at the beginning - 0 seconds
  cuein: 15,

  // where the waveform for this track should end
  // ex (Waveform will end at 30 second into this track)
  // DEFAULT duration of the track
  cueout: 30,

  // custom class for unique track styling
  customClass: 'vocals',

  // custom background-color for the canvas-drawn waveform
  waveOutlineColor: '#f3f3f3',

  // interaction states allowed on this track.
  // DEFAULT - all true
  states: {
    cursor: true,
    fadein: true,
    fadeout: true,
    select: true,
    shift: true,
  },

  // pre-selected section on track.
  // ONLY ONE selection is permitted in a list of tracks, will take most recently set if multiple passed.
  // This track is marked as 'active'
  selected: {
    // start time of selection in seconds, relative to the playlist
    start: 5,

    // end time of selection in seconds, relative to the playlist
    end: 15,
  },

  // value from -1 (full left pan) to 1 (full right pan)
  stereoPan: 0,

  // pass a custom function which will receive the last graphnode for this track and the mastergainnode.
  // if you pass a function, you must connect these two nodes to hear sound at minimum.
  // if you need to clean something up when the graph is disposed, return a cleanup function. Waveform Playlist will cleanup the nodes passed as arguments.
  effects: function(graphEnd, masterGainNode, isOffline) {
    var reverb = new Tone.Reverb(1.2);

    Tone.connect(graphEnd, reverb);
    Tone.connect(reverb, masterGainNode);

    return function cleanup() {
      reverb.disconnect();
      reverb.dispose();
    }
  }
}

Playlist Events

Waveform Playlist uses an instance of event-emitter to send & receive messages from the playlist.

import EventEmitter from "event-emitter";
import WaveformPlaylist from "waveform-playlist";

var playlist = WaveformPlaylist(
  {
    container: document.getElementById("playlist"),
  },

  // you can pass your own event emitter
  EventEmitter()
);

// retrieves the event emitter the playlist is using.
var ee = playlist.getEventEmitter();

An example of using the event emitter to control the playlist can be found in /dist/js/examples/emitter.js

Events to Invoke

event arguments description
play start:optional, end:optional Starts playout of the playlist. Takes optional Number parameters in seconds start and end to play just an audio segment. start can be passed without an end to play to the end of the track.
pause none Pauses playout of the playlist.
stop none Stops playout of the playlist.
rewind none Stops playout if playlist is playing, resets cursor to the beginning of the playlist.
fastforward none Stops playout if playlist is playing, resets cursor to the end of the playlist.
clear none Stops playout if playlist is playing, removes all tracks from the playlist.
record none Starts recording an audio track. Begins playout of other tracks in playlist if there are any.
zoomin none Changes zoom level to the next smallest entry (if one exists) from the array zoomLevels.
zoomout none Changes zoom level to the next largest entry (if one exists) from the array zoomLevels.
trim none Trims currently active track to the cursor selection.
statechange cursor / select / fadein / fadeout / shift Changes interaction state to the state given.
fadetype logarithmic / linear / sCurve / exponential Changes playlist default fade type.
newtrack File Loads File object into the playlist.
volumechange volume, track Set volume of track to volume (0-100)
mastervolumechange volume Set a new master volume volume (0-100)
select start, end, track:optional Seek to the start time or start/end selection optionally with active track track.
startaudiorendering wav / buffer Request for a downloadable file or web Audio buffer that represent the current work
automaticscroll true/false Change property isAutomaticScroll.
continuousplay true/false Change property isContinuousPlay.
linkendpoints true/false Change property linkEndpoints.
annotationsrequest none Requests to download the annotations to a json file.
stereopan panvalue, track Set pan value of track to panvalue (-1-1)

Events to Listen to

event arguments description
select start, end, track Cursor selection has occurred from start to end with active Track track.
timeupdate playbackPosition Sends current position of playout playbackPosition in seconds.
scroll scrollLeft Sends current position of scroll scrollLeft in seconds.
statechange state Sends current interaction state state.
shift deltaTime, track Sends deltaTime in seconds change for Track track
mute track Mute button has been pressed for track
solo track Solo button has been pressed for track
removeTrack track Remove button has been pressed for track
changeTrackView track, opts Collapse button has been pressed for track
volumechange volume, track Volume of track has changed to volume (0-100)
mastervolumechange volume Master volume of the playlist has changed to volume (0-100)
audiorequeststatechange state, src Loading audio src (string or File) is now in state state (Number)
loadprogress percent, src Loading audio src has loaded percent percent (0-100)
audiosourcesloaded none Audio decoding has finished for all tracks
audiosourcesrendered none Tracks are rendered to the playlist
audiosourceserror err Error thrown while loading tracks
finished none Event fired when cursor ( while playing ) reaches the end (maximum duration)
audiorenderingstarting offlineCtx, setUpPromiseArray Event fired after the OfflineAudioContext is created before any rendering begins. If any setup is async before offline redering, push a promise to the setUpPromiseArray.
audiorenderingfinished type, data Return the result of the rendering in the desired format. type can be buffer or wav and can be used to dertermine the data type. When type is wav, data is a blob object that represent the wav file.
stereopan panvalue, track Pan value of track has been changed to panvalue

Tests

npm test

Development without example changes

npm install && npm start

This will install dependencies and start the webpack server.

Development with example changes

gem install jekyll

Jekyll is needed if changes to the example pages will be done.

npm install && npm run dev

This will build and watch the jekyll site and startup the webpack dev server.

Credits

Originally created for the Airtime project at Sourcefabric

The annotation plugin has been sponsored by a fond Italian TED volunteer transcriber hoping to make the transcription process of TEDx talks easier and more fun.

Books

Currently writing: Mastering Tone.js. Get notified by Leanpub when I publish.

License

MIT License

waveform-playlist's People

Contributors

alexander-daniel avatar dependabot[bot] avatar faroit avatar iliazeus avatar lysdexic-audio avatar megidd avatar mgrachten avatar msakrejda avatar naomiaro avatar oguz3 avatar p-himik avatar rowild avatar scrawlon avatar willena avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

waveform-playlist's Issues

Record during playback

Hello, congratulations for the software, it works great!
I'm doing some experiments trying to turn it into a small DAW: everything works (even recording with playback of other tracks) but during the playback of all tracks I hear a substantial delay of my recording, so it's out of time compared to the other tracks.
Any idea how to handle this? Maybe are there some options to decrease sound quality and manage the session, increasing the performance?
thank you,
ciao,
Marco

Get loading-data?

Hi! I'm loading some big and long files and it takes 10-15 seconds to load but all I see in the start is a white page and I don't know if it's loading or not.
I would wish to impant a loading-bar but I'll need to get the data of how much have bin loaded so far.
Is it possible to get this data some how?

Thanks!

Question: "Rendering waveform in the fly?"

Hi
I am using wavesurfer.js and it only renders the waveform once an mp3 was entirely loaded. Does this library have the same limitation? Or can it somehow render what's loaded before finishing the entire download?

Usage with electron

Hi,

I try to run the player in an electron (https://github.com/electron/electron) app. I encounter this issue, and I don't really understand what "worker!" means.

I just started a blank electron project, added the dependancy to your lib and paste your getting started code.

Do you have an idea of what I am missing ?

Here is the stack trace:

App threw an error during load
Error: Cannot find module 'worker!./track/recorderWorker.js'
    at Module._resolveFilename (module.js:455:15)
    at Function.Module._resolveFilename (/private/var/www/PickNinja/node_modules/electron/dist/Electron.app/Contents/Resources/electron.asar/common/reset-search-paths.js:35:12)
    at Function.Module._load (module.js:403:25)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/private/var/www/PickNinja/node_modules/waveform-playlist/lib/Playlist.js:47:23)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)

Touch compatibility for audio tools

I played with the editor on an 7-inch Android Tablet and the Select audio region and Shift audio in time tools are not touch compatible. Maybe not on top of priority list, but might be useful in some projects.

Is there a way to reset/clear the playlist ?

Hello, I'm using your library since today and I have to say you have done a great job !
Just Im wondering how do I reset de playlist ? I need to remove all the tracks before adding new ones.

something like playlist.removeAll() or playlist.clear()

Thanks in advance

Lorenzo

Effects

One thing that could be useful is if it were possible to add effects to tracks. I think it would be easy to add this functionality to the Track object. You could use a setEffects() method that would take an array of Web Audio nodes and connect them in the string of gain nodes that are currently used. If this sounds useful to other people too, I could write the code and do a PR.

Use react

Hey,

Pretty cool project which provides a lot of inspiration. Have you ever thought about using react to render the UI? I'm coming from a strong react background. So I'm wondering, why you're going the painful way of rendering all this manually? Just out of curiosity.

Regards

Asyncronous playlist - ajax

Hi, if i have a dynamic playlist container. When i refresh playlist container with another playlist trough Ajax request and i Press play, browser play old audio and new audio simoultanesly. Result is bad... There is a way to clear audiocontext and re-init new playlist class without refesh page? I have tried audiocontext.close() but After play Burton not work...

Error when exporting in WAV in Safari

Hi,
I encountered the following error while exporting the mix in WAV with Safari (desktop and mobile) :

TypeError : undefined is not an object (evaluating 'this.offlineAudioContext.startRendering().then').

Regards,
Emmanuel

Overlapping recording

Hi,

I think i have found a potential bug in your code, or I am doing something wrong.
Issue is occurring when new recording is being done, and it is overlapping with previous track (if there is any).
So in example, you can hear echo of previous track in new recorded track.
And if you for example record a third, you hear echoes of previous two track into third track.

Can it be separate recording for each track, without overlapping from previous ones?

Is there a way to re-order the tracks?

Say we want to prepend or append to the current trackList. Is there a way to insert a new track with an index so we can specify where it gets loaded?

Thanks!

Solo/Mute not obeyed on seek

Noticing a new problem which isn't resolved by updating to latest version.

The solo and mute buttons work fine until I seek to a new part, when all the audio is heard as if no buttons are depressed. If I pressed Solo on track 1, once I seek all tracks are heard again, even though that button will still appear depressed on the screen. Same true for mute. Track volumes appear to function normally and persist after seeking

http://www.chorosemvoce.com/ for an example. Can anyone replicate this?

Waveforms doesn't update when zooming out

Hi! When I'm zooming out in the example and in my own project the waveform doesn't update the part of the waveform you see. If I scroll to the right the waveform have updated but not in the part that I see to begin with.

This only happens on zooming out, never on zooming in.

Saving & Loading Playlists

Is there a method developed to save and load the playlist using something like AJAX? Allowing a user without access to the server or code to upload audio in the track-drop class div, and when they refresh and/or return to the website later their edits are essentially saved? I think this would be a helpful addition.

I'm guessing this could be accomplished using AJAX by posting the data in the array that is sent to the console using playlist.getInfo() in emitter.js and then calling another AJAX function in the WaveformPlaylist.init() function that retrieves this data, that can then be loaded as an array in the playlist.load() both in web-audio-editor.js? Maybe a similar method could be used for storing that data in localStorage?

customClass not included in `npm i` lib code, version 2.6.1

Hey there!

I think its just a case where the transpilation didn't happen.

I see it in the ES2015 src here:
https://github.com/naomiaro/waveform-playlist/blob/master/src/Track.js#L523

However in the transpiled lib after installing with npm, I see the following:

            return (0, _h2.default)('div.channel-wrapper' + audibleClass, {
                attributes: {
                    "style": 'margin-left: ' + channelMargin + 'px; height: ' + data.height * numChan + 'px;'
                } }, channelChildren);

Is it just a case of the transpiled code did not make it into the npm publish?

Thanks as always!

Stereo Panning?

Is there a way to work with stereo panning when using this webapp? I would love to use this for simple multi-track mixing.

problem with 'finished' event

Hey Naomiaro,

I'm still working with your project and it's awesome !
However I think I've found an issue with the 'finished' event. When you start playing from the very start of the playlist, it doesn't emit the 'finished' event once it has reached the end.

Display the entire track by default

Sorry if I missed this in the documentation somewhere, but is there a way to configure the playlist to show the entire length of the track from start to end by default? The current behavior seems to only show a portion of the track by default unless you zoom out. Is this the expected behavior? One workaround is to adjust the zoom level depending on the track duration. But is there is recommended way to do this?

Thanks!

loadprogress event should fire if all sources are loaded

Another day, another proposal ;-)

Currently the ee.on('loadprogress') emits the individual load progress of each source. I am rather interested in general loading indicator that fires when all sources are loaded.

maybe .on('finishedLoading') ?

Exclusive Solo / Radio Solo / Shift+solo function

Just want to thank you for this great project. It is very helpful for us and we want to deploy on a public website where we want to display results for audio source separation. In source separation you normally listen to individual tracks of a mixture and want to switch to these tracks with a click of a button.

In Audacity you can do this by holding shift and click on the solo buttons. This basically toggles soloed on one track an disables it on all other tracks.

The best fit for a corresponding user interface would be a radio button, where only one option is allowed to be active a the same time.

So my feature proposal would be to add a radiosolo option to each track that would display a third button which allows to toggle between the tracks.

How to re-render waveform of the track

I am developing a undo/redo functionality for a player, I am able to handle almost all events except trimming, I used a method setCues and it sets perfect values but the waveform on UI does not re-render I tried all methods which I though will work but none worked, can you please help with this.

CAn't use the player with Angular 2

Hi,
first of all thank you for your project !
I'm quite a beginner with the web technologie and i'm trying to use your package for a Angluar 2 project.
However I didn't succeed to make it work...

here is my code :

import { Component, OnInit } from '@angular/core';
import { WaveformPlaylist } from 'waveform-playlist';

@Component( {
  selector: 'player',
  template: `<div id="playlist"> loading player ... </div>`
})
export class PlayerComponent implements OnInit {

  tracks : any;

  ngOnInit() : void {
    this.tracks = WaveformPlaylist.init({
      samplesPerPixel: 3000,
      mono: true,
      waveHeight: 70,
      container: document.getElementById('playlist'),
      state: 'cursor',
      colors: {
        waveOutlineColor: '#E0EFF1',
        timeColor: 'grey',
        fadeColor: 'black'
      },
      controls: {
        show: true,
        width: 200
      },
      zoomLevels: [500, 1000, 3000, 5000]
    });
  }
}

and here is the error I get :

Error: (SystemJS) XHR error (404 Not Found) loading http://localhost:3000/waveform-playlist
	wrapFn@http://localhost:3000/node_modules/zone.js/dist/zone.js:1055:30
	ZoneDelegate.prototype.invokeTask@http://localhost:3000/node_modules/zone.js/dist/zone.js:424:17
	Zone.prototype.runTask@http://localhost:3000/node_modules/zone.js/dist/zone.js:191:28
	ZoneTask/this.invoke@http://localhost:3000/node_modules/zone.js/dist/zone.js:486:28
	
	Error loading http://localhost:3000/waveform-playlist as "waveform-playlist" from http://localhost:3000/app/player.component.js
Trace de la pile :
(SystemJS) XHR error (404 Not Found) loading http://localhost:3000/waveform-playlist
	wrapFn@http://localhost:3000/node_modules/zone.js/dist/zone.js:1055:30
	ZoneDelegate.prototype.invokeTask@http://localhost:3000/node_modules/zone.js/dist/zone.js:424:17
	Zone.prototype.runTask@http://localhost:3000/node_modules/zone.js/dist/zone.js:191:28
	ZoneTask/this.invoke@http://localhost:3000/node_modules/zone.js/dist/zone.js:486:28
	
	Error loading http://localhost:3000/waveform-playlist as "waveform-playlist" from http://localhost:3000/app/player.component.js

Do you have any idea on what I'm doing wrong ?

Feature Idea: playlist.destroy()

Sometimes if you're dealing with multiple waveform-playlist instances, it would be nice to be able to destroy one. This is sort of possible right now, however if the playlist is currently loading a track, it will continue to execute that logic (and any event handlers associated with loading that the user has set up), regardless if you've cleared or deleted the instance.

Ideally, the loading promises would be cancellable, and when you call playlist.destroy() it cleans everything up, the audioContext, the DOM elements, and also would cancel any pending promises!

I'll think through this one a bit more, but just dropping this issue in case there could be a nice discussion.

seek doesn't change live

In Fx Dev, moving the seek marker doesn't instantly change the play point. Have to []stop then >play to get it to play at the new marker point.

Big memory usage when recording

Dear @naomiaro , I was testing the microphone example. It uses extensive memory while recording to the point my firefox hang up after 5 minutes or so. Is this expected?

Thank you,

Specify starting track gain

I'd like to be able to specify gain when loading a track:

playlist.load([
  {src: 'drums.mp3', gain: 0.5}
])

Is something similar already possible?

Trouble Installing on CLOUD9.io Workspace

Hi,

I'm trying to put your project on a workspace on cloud9. But I can't use it.

I explain :

I install the node_modules and after use your command npm install waveform-playlist and the folder was created. But after I can't start the projet because I haven't got some html files. I try to move "dist" folder into the good repertory but nothing working.

I really want to install it on cloud9 for school project. So please can you help me ?

Sorry for my bad English.

Best Regards,

RcK.

exportWorker is undefined

this is really awesome,
but when I want to download simple file like wave,
get this error in browser console

TypeError: _this4.exportWorker is undefined[Learn More]  waveform-playlist.var.js:2068:12

I try my file in this address, as you can guess everything works fine.
Thank you <3

Issues with export to WAV function

Hi,
I'm playing with the full editor demo (online and dist folder) and I can't get the export to WAV function to work. Console shows "TypeError: Cannot read property 'postMessage' of undefined".

Any fix for the same?

Thanks in advance

Emmanuel

Set track styles

I would propose to add custom style element to the playlist tracks and also allow tracks to have unique identifiers and a class attribute which would enable to set the styles later.

something like:

{
  //a media path for XHR or a File object.
  "src": "media/audio/BassDrums30.mp3",

  //name that will display in the playlist control panel.
  "name": "Drums",

  // set id for track
  "id": "drums",
}

that way, one could add a custom css like this

 .playlist .controls #drums header{
      background-color: red;
}

loop

Hi Naomi,

It would be great if your multi track audio player could have a loop-function too. Also it would be nice if a user could specify the amount of repeats using a special button and the part of the audio that has to be repeated. For my students I'm using play-along-tracks which have 4 or 8 metronome clicks. When a student chooses to have the track - let's say - repeated 3 times, it has to repeat/loop the part that comes after the metronomes, because you want to listen to the metronome only once.

Would be great.

Kind regards,
Derk

How do I install?

Hi! I'm trying to download waveform-playlist to see how the example "stem-tracks" are made but what ever branch I'm downloading I can't find the html file. Where can I get the git-hub examples?

Thanks!

Rewind with select: scroll does not update

Dear,

When isAutomaticScroll = true, when the timeline is scrolled and when a "select" event is emitted to an anterior time, scroll does not update.

Here is the code to update below to fix.(in module 59)

Thank you

_createClass(_class, [{
key: 'hook',
value: function hook(node) {
var playlist = this.playlist;
if (!playlist.isScrolling) {
var el = node;

        if (playlist.isAutomaticScroll && playlist.isPlaying()) {
          var rect = node.getBoundingClientRect();
          var cursorRect = node.querySelector('.cursor').getBoundingClientRect();

          if (cursorRect.right > rect.right || cursorRect.left < rect.left) { // Update is here
          //if (cursorRect.right > rect.right) {
            playlist.scrollLeft = playlist.playbackSeconds;
          }
        }

        var left = (0, _conversions.secondsToPixels)(playlist.scrollLeft, playlist.samplesPerPixel, playlist.sampleRate);

        el.scrollLeft = left;
      }
    }

Auto scrolling while playing

Is there a way for the playlist to automatically scroll when the end of DIV is reached ?

btw I don't know how to label an issue with the "question" label..

Change Name Of Wav download file ??

Hi There,

is there anyway to change the name of the download file ? Not just a date and time etc ?

Also at what rate are the WAV files ? 44,100 Hz ? is there anyway to change this ? Or even add MP3 ?

Thanks for your help !

Cheers
D

Is there an easy way to delete a track?

Hi,
First of all, thanks for this project, it is exactly what I searched for weeks now.

I wonder if there is an easy way to delete a single track? It doesn't seem to have a specific method for the same. Maybe by getting the data of the track to delete (getTrackDetails() ?) and by removing it from the complete playlist details?

Kind regards,

Emmanuel

Change master volume?

Hi again! I'm wondering if there is a way to change the master volume of the loaded tracks?
Thanks!

Improve performance on Chrome and Firefox

Currently, the performance of waveform-playlist is not optimal when playing back many tracks and when using chrome or firefox instead of safari.

For example on my macbook air I almost reach 100% CPU with chrome or firefox, which results in kind of choppy animations for some users.

It turns out when I turn of the waveform rendering, CPU usage goes down to a minimum of a few percent. You can easily reproduce this by commenting out this line. I tried to dig deeper into the animation track render code and I've managed to bring the CPU usage down by a few percent, but not as much as I hoped.

Ideally my suggestion would be to have a high performance mode that renders the track waveforms only once when the tracks are loaded and only animates the playhead while playing instead of re-rendering the waveforms to show the progress.

@naomiaro what do you think?

Alter playback speed?

After a few teething problems due to my lack of experience, now enjoying building some multitracks with this! I teach a Brazilian style of music called choro and you can see the tracks I've built up below.

http://chorotest.hol.es/

Is there a way to implement the webaudio playback speed feature, using a global slider like the master volume control. Then my students could speed up or slow down the track slightly (within reason).

https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/WebAudio_playbackRate_explained

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.