动态创建多个具有唯一名称的 wavesurfer 对象 [英] Dynamically create multiple wavesurfer objects with unique names

查看:52
本文介绍了动态创建多个具有唯一名称的 wavesurfer 对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不确定我的措辞是否正确,但这是我想要做的.

我正在使用一个函数在页面上呈现多个 wavesurfer 实例.

这是开箱即用的,因为您只需声明 wavesurfer 的每个单独实例:

var wavesurfer1 = WaveSurfer.create({容器:domEl,条宽:3,.....var wavesurfer2 = WaveSurfer.create({容器:domEl,条宽:3,.....

但我正在预加载 JSON 存储的波形数据,而不是在页面加载时加载任何音频文件,只有当用户单击播放按钮时才加载音频文件.此外,实例的数量及其 ID 将动态创建.

我的逻辑正常工作,但我无法针对 wavesurfer 的每个唯一实例进行定位,因为它们并不是唯一的 - 因此我的问题是,我在官方网站(或 git) 关于针对单个实例.我认为 container 是可能的,但找不到有关如何执行此操作的任何信息,因此我正在尝试另一种方式.

在呈现 wavesurfer 的每个实例的函数中,我们有这个(domEl 被传递到函数中并创建一个唯一的 divid> 对于每个波形容器):

var wavesurfer = WaveSurfer.create({容器:domEl,条宽:3,waveColor: '#CCC',progressColor: '白色',后端:'媒体元素',媒体类型:'音频',身高:80,cursorColor: '白色',响应:真实,隐藏滚动条:真});

以及加载实际音频的函数:

$('.m-btn-player').on('click', function() {id = $(this).data("id");var url = "/play?id="+id;wavesurfer.load(url);wavesurfer.play();})

这是可行的,但是由于 wavesurfer 的每个实例都声明为 wavesurfer,因此无论单击哪个播放按钮,它都会将音频加载到每个实例中.

我认为我可以做的是使用动态生成的名称在渲染函数中声明 wavesurfer 的每个实例,即:

//`id` 被传递给函数var wavesurfer+id = WaveSurfer.create({容器:domEl,条宽:3,....

然后:

wavesurfer+id.load(url);wavesurfer+id.play();

但这行不通(我什至认为从我读到的关于动态变量名称的内容来看这是不可能的).

我还读到,我可能应该将哈希图用于此类用途,但不知道如何使用它们,因此如果是这种情况,或者您可以看到我可以完成这项工作的另一种方式,我将非常感激一些提示.

如果这种方法完全错误,我如何定位多个 wavesurfer 实例而不声明每个实例的对象名称?我在任何地方都找不到任何可以解释如何执行此操作的内容.

解决方案

经过反复试验,我破解了它.

你需要设置一个对象数组:

var wavesurfer = [];

然后在渲染函数中创建每个实例时将每个单独的 id 传递给它:

function render(id, selector, peaks, url) {var domEl = document.createElement('div');domEl.setAttribute("id", "t-"+id);document.querySelector(selector).appendChild(domEl);trackid = "t"+id;wavesurfer[trackid] = WaveSurfer.create({容器:domEl,条宽:3,waveColor: '#CCC',progressColor: '白色',后端:'媒体元素',媒体类型:'音频',身高:80,cursorColor: '白色',响应:真实,隐藏滚动条:真});//确保以相同的方式引用每个方法...wavesurfer[trackid].drawBuffer();wavesurfer[trackid].load(url, peaks, false);//false 阻止预加载音频文件返回 wavesurfer[trackid];}

调用渲染函数:

render(1, ".tk1", [....], 'http://example.com/file.mp3');

然后你可以使用对象标识符来定位每个玩家,在这个例子中传递给函数的id是1:

wavesurfer[t1].playPause();

所以用例可能是:

<button type="button" onClick="wavesurfer['t1'].playPause();">PLAY</button><脚本>渲染(1, ".tk1", [-0.39,0.4,-0.9,0.91,-0.32,0.34,-0.95,0.98,-0.54,0.74,-0.9,0.91,-0.33,0.37,-0.96,0.98,--0.9,0.91,-0.79,0.76,-0.95,0.95,-0.88,0.87,-0.91,0.94,-0.55,0.6,-0.97,0.96,-0.43,0.43,-0.91,0.5,10,-0.91,0.5,10,--0.98,0.94,-0.55,0.76,-0.91,0.91,-0.33,0.37,-0.98,0.98,-0.39,0.41,-0.92,0.91,-0.31,0.34], 'http://example.com/文件.mp3');

<div class="tk2"><button type="button" onClick="wavesurfer['t2'].playPause();">PLAY</button><脚本>渲染(2, ".tk2", [-0.39,0.4,-0.9,0.91,-0.32,0.34,-0.95,0.98,-0.54,0.74,-0.9,0.91,-0.33,0.37,-0.96,0.98,-0.96,0.98,--0.9,0.91,-0.79,0.76,-0.95,0.95,-0.88,0.87,-0.91,0.94,-0.55,0.6,-0.97,0.96,-0.43,0.43,-0.91,0.5,10,-0.91,0.5,10,--0.98,0.94,-0.55,0.76,-0.91,0.91,-0.33,0.37,-0.98,0.98,-0.39,0.41,-0.92,0.91,-0.31,0.34], 'http://example.com/file2.mp3');

Not sure I'm wording this correctly but here is what I'm trying to do.

I am using a function to render multiple instances of wavesurfer on a page.

Out of the box this is straight forward, as you just declare each separate instance of wavesurfer :

var wavesurfer1 = WaveSurfer.create({
  container: domEl,
  barWidth: 3,
  .....

var wavesurfer2 = WaveSurfer.create({
  container: domEl,
  barWidth: 3,
  .....

But I'm preloading JSON stored waveform data and NOT loading any audio file at page load, only when a user clicks the play button should the audio file load. Also the amount of instances and their id's will be created dynamically.

I've got the logic working but I'm having trouble targeting each unique instance of wavesurfer as, well, they are not unique - hence my question, and I can't find any information on the official site (or git) about targeting individual instances. I would assume that it's possible by the container but can't find any info about how to do this, so I'm trying it another way.

In the function that renders each instance of wavesurfer we have this (domEl is being passed into the function and creates a unique div and id for each waveform container) :

var wavesurfer = WaveSurfer.create({
  container: domEl,
  barWidth: 3,
  waveColor: '#CCC',
  progressColor: 'white',
  backend: 'MediaElement',
  mediaType:'audio',
  height: 80,
  cursorColor: 'white',
  responsive: true,
  hideScrollbar: true
});

And the function that loads the actual audio :

$('.m-btn-player').on('click', function() {

  id = $(this).data("id");
  var url = "/play?id="+id;
  wavesurfer.load(url);
  wavesurfer.play();

})

This works, but as each instance of wavesurfer is declared as wavesurfer it loads the audio into every single instance no matter which play button is clicked.

What I thought I could do was declare each instance of wavesurfer in the render function with a dynamically generated name i.e :

// `id` is passed to the function

var wavesurfer+id = WaveSurfer.create({
container: domEl,
barWidth: 3,
....

Then :

wavesurfer+id.load(url);
wavesurfer+id.play();

But this doesn't work (and I don't even think it's possible from what I've read about dynamic variable names).

I've also read that I should possibly be using hashmaps for something like this but have no idea how to use them, so if that is the case, or you can see another way I can make this work I would really appreciate some pointers.

If this approach is entirely wrong how do I target multiple instances of wavesurfer without declaring the object name for each one? I can't find anything that explains how to do this anywhere.

解决方案

After much trial and error I cracked it.

You need to set up an object array :

var wavesurfer = [];

And then pass each individual id into it when creating each instance inside your render function :

function render(id, selector, peaks, url) {

  var domEl = document.createElement('div');
  domEl.setAttribute("id", "t-"+id);
  document.querySelector(selector).appendChild(domEl);

  trackid = "t"+id;

  wavesurfer[trackid] = WaveSurfer.create({
    container: domEl,
    barWidth: 3,
    waveColor: '#CCC',
    progressColor: 'white',
    backend: 'MediaElement',
    mediaType:'audio',
    height: 80,
    cursorColor: 'white',
    responsive: true,
    hideScrollbar: true
  });

  // Make sure you reference each method the same way...

  wavesurfer[trackid].drawBuffer();
  wavesurfer[trackid].load(url, peaks, false); //false prevents preload of audio file

  return wavesurfer[trackid];
}

Call the render function :

render(1, ".tk1", [....], 'http://example.com/file.mp3');

Then you can target each player using the object identifier, in this instance the id passed to the function was 1:

wavesurfer[t1].playPause();

So a use case could be :

<div class="tk1">
  <button type="button" onClick="wavesurfer['t1'].playPause();">PLAY</button>
  <script>
  render(1, ".tk1", [-0.39,0.4,-0.9,0.91,-0.32,0.34,-0.95,0.98,-0.54,0.74,-0.9,0.91,-0.33,0.37,-0.96,0.98,-0.9,0.91,-0.79,0.76,-0.95,0.95,-0.88,0.87,-0.91,0.94,-0.55,0.6,-0.97,0.96,-0.43,0.43,-0.91,0.91,-0.51,0.4,-0.98,0.94,-0.55,0.76,-0.91,0.91,-0.33,0.37,-0.98,0.98,-0.39,0.41,-0.92,0.91,-0.31,0.34], 'http://example.com/file.mp3');
  </script>
</div>

<div class="tk2">
  <button type="button" onClick="wavesurfer['t2'].playPause();">PLAY</button>
  <script>
  render(2, ".tk2", [-0.39,0.4,-0.9,0.91,-0.32,0.34,-0.95,0.98,-0.54,0.74,-0.9,0.91,-0.33,0.37,-0.96,0.98,-0.9,0.91,-0.79,0.76,-0.95,0.95,-0.88,0.87,-0.91,0.94,-0.55,0.6,-0.97,0.96,-0.43,0.43,-0.91,0.91,-0.51,0.4,-0.98,0.94,-0.55,0.76,-0.91,0.91,-0.33,0.37,-0.98,0.98,-0.39,0.41,-0.92,0.91,-0.31,0.34], 'http://example.com/file2.mp3');
  </script>
</div>

这篇关于动态创建多个具有唯一名称的 wavesurfer 对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆