【问题标题】:Merge multiple audio buffer in to one by given position in real time - Web Audio Context通过给定位置实时将多个音频缓冲区合并为一个 - Web Audio Context
【发布时间】:2018-11-29 05:30:45
【问题描述】:

我正在尝试使用 jquery UI 拖放来混合多个音频。意味着我将在音频上下文中动态添加轨道,并将其放在容器上。使用 XMLHttpRequest 删除后,我可以获取跟踪缓冲区。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>jQuery UI Sortable - Connect lists</title>
  <style>
  body {
		font-family: Arial, Helvetica, sans-serif;
	}

	table {
		font-size: 1em;
	}

	.ui-draggable, .ui-droppable {
		background-position: top;
	}
  #sortable1, #sortable2 {
    border: 1px solid #eee;
    width: 142px;
    min-height: 20px;
    list-style-type: none;
    margin: 0;
    padding: 5px 0 0 0;
    float: left;
    margin-right: 10px;
  }
  #sortable1 li, #sortable2 li {
    margin: 0 5px 5px 5px;
    padding: 5px;
    font-size: 1.2em;
    width: 120px;
  }
  </style>
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script>
  
	var buffers = [];
  
	window.AudioContext = (window.AudioContext ||
        window.webkitAudioContext ||
        window.mozAudioContext ||
        window.oAudioContext ||
        window.msAudioContext);

    if (!AudioContext) alert('This site cannot be run in your Browser. Try a recent Chrome or Firefox. ');

    var audioContext = new AudioContext();
  
	$( function() {
		$( "#sortable1" ).droppable({
			helper: "clone",
			revert: "invalid",
			accept: ".ui-state-highlight",
			drop: function(e, ui){
				console.log(ui.draggable.data('url'));
				
			}
		}).disableSelection();


		$( "#sortable2").sortable({
			revert: true,
			connectWith: ".connectedSortable"
		}).disableSelection();

		
	function loadMusic(url) {
        var req = new XMLHttpRequest();
        req.open( "GET", url, true );
        req.responseType = "arraybuffer";
        req.onreadystatechange = function (e) {
            if (req.readyState == 4) {
                if(req.status == 200)
                    audioContext.decodeAudioData(req.response,
                        function(buffer) {
							var id = '_' + Math.random().toString(10).substr(2, 9)
                            buffers[id] = {
								buffer: buffer,
								start: 1, 
								to: 5							
							};
                        }, onDecodeError);
                else
                    alert('error during the load.Wrong url or cross origin issue');
            }
        };
        req.send();
    }
	
	// I have buffers array, how I can merge the dropped tracks by dynamic positions using start and end
  
		
	} );
	
  </script>
</head>
<body>
 
<ul id="sortable1" class="connectedSortable">
</ul>
 
<ul id="sortable2" class="connectedSortable">
  <li class="ui-state-highlight" data-url="https://twgljs.org/examples/sounds/DOCTOR%20VOX%20-%20Level%20Up.mp3">Song 1</li>
  <li class="ui-state-highlight" data-url="https://freesound.org/data/previews/449/449593_7037-lq.mp3">Song 1</li>
  <li class="ui-state-highlight" data-url="https://freesound.org/data/previews/449/449554_2454046-lq.mp3">Song 1</li>
</ul>
 
 
</body>
</html>

我现在可以做些什么来合并丢弃的曲目并实时播放?我对 javascript 音频上下文非常陌生。

【问题讨论】:

    标签: javascript jquery jquery-ui audiocontext webkitaudiocontext


    【解决方案1】:

    我会建议 UI 与此示例更相似:

    https://jqueryui.com/droppable/#photo-manager

    您的最终可能会变得更复杂,但这是一个很好的示例,说明了如何在 Web 应用程序中使用拖放 (DnD) 功能。考虑到用户需要执行某些任务:

    • 将选择移动到特定位置
    • 在该位置调整选择的位置
    • 从位置中删除选择

    此外,您是否希望他们对音频 sn-p 进行切片?让它变小?调整音频文件的其他设置?

    考虑下面的代码。

    var buffers = [];
    
    window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.oAudioContext || window.msAudioContext;
    
    if (!AudioContext) {
      alert('This site cannot be run in your Browser. Try a recent Chrome or Firefox.');
    }
    
    var audioCtx = new AudioContext();
    
    $(function() {
      $("#output").sortable({
        revert: true,
        accept: ".clip",
        handle: ".handle",
        placeholder: "ui-state-highlight",
        receive: function(e, ui) {
          var clip = ui.item;
          console.log(clip.data("url"));
        },
        update: function(e, ui) {
          if (ui.item.find(".ui-icon-close").length < 1) {
            ui.item.append("<span class='ui-icon 	ui-icon-grip-dotted-vertical handle left'></span>");
            ui.item.append("<span class='ui-icon ui-icon-close right'></span>");
            $("#output .ui-icon-close").click(function(e) {
              $(e.target).parent().remove();
            });
          }
        }
      }).disableSelection();
    
      $("#song-clips li").draggable({
        helper: "clone",
        revert: "invalid",
        connectToSortable: "#output"
      });
    
      /*
      function loadMusic(url, ac) {
        var req = $.ajax({
          cache: false,
          url: url,
          responseType: "arraybuffer",
          processData: false,
          success: function(response) {
            ac.decodeAudioData(response,
              function(buffer) {
                var id = '_' + Math.random().toString(10).substr(2, 9);
                buffers[id] = {
                  buffer: buffer,
                  start: 1,
                  to: 5
                };
              }, onDecodeError);
          },
          error: function(xhr, error) {
            alert('Error during the load. ' + error);
          }
        });
      }
      */
    });
    body {
      font-family: Arial, Helvetica, sans-serif;
    }
    
    table {
      font-size: 1em;
    }
    
    .ui-draggable,
    .ui-droppable {
      background-position: top;
    }
    
    .connectedSortable {
      width: 142px;
      min-height: 20px;
      list-style-type: none;
      margin: 0;
      padding: 5px 0 0 0;
    }
    
    .connectedSortable li {
      margin: 0 5px 5px 5px;
      padding: 5px;
      font-size: 1.2em;
      width: 120px;
    }
    
    .song-wrapper {
      width: 200px;
      margin-bottom: 3px;
    }
    
    .trash-wrapper {
      width: 200px;
      float: right;
    }
    
    #output {
      width: 100%;
      height: 48px;
      border: 1px solid #eee;
      padding: 5px 3px;
      overflow-x: scroll;
      white-space: nowrap;
    }
    
    #output li {
      min-height: 20px;
      margin: 0;
      padding: 5px;
      float: left;
      width: 120px;
    }
    
    #output .ui-icon-close:hover {
      background-color: #fff;
      border: 1px solid #999;
      border-radius: 3px;
    }
    
    #output .ui-icon-grip-dotted-vertical {
      cursor: move;
    }
    
    #output .handle {
      margin-top: 3px;
    }
    
    .left {
      float: left;
    }
    
    .right {
      float: right;
    }
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    
    <div class="ui-helper-clearfix">
      <div class="ui-widget song-wrapper">
        <div class="ui-widget-header">Audio Clips</div>
        <div class="ui-widget-content">
          <ul id="song-clips" class="connectedSortable">
            <li class="ui-state-default clip" data-url="https://twgljs.org/examples/sounds/DOCTOR%20VOX%20-%20Level%20Up.mp3">Clip 1</li>
            <li class="ui-state-default clip" data-url="https://freesound.org/data/previews/449/449593_7037-lq.mp3">Clip 2</li>
            <li class="ui-state-default clip" data-url="https://freesound.org/data/previews/449/449554_2454046-lq.mp3">Clip 3</li>
          </ul>
        </div>
      </div>
    </div>
    <div class="ui-widget">
      <div class="ui-widget-header">Final Output</div>
      <div class="ui-widget-content">
        <ul id="output" class="connectedSortable">
        </ul>
      </div>
    </div>

    【讨论】:

    • 谢谢你的回答兄弟。那很有帮助。但是合并丢弃的曲目并实时播放呢?
    • @TareqAziz 很高兴这有帮助。如果有帮助,请投票并将其标记为答案。你希望它如何播放曲目?按钮点击?处理它并在需要时发布另一个问题。
    • 我想通过点击按钮来播放曲目。答案只是关于拖放我已经知道那个兄弟。需要实时播放是删除多个曲目后的主要问题。喜欢 looplabs (looplabs.com)
    • @TareqAziz 我不确定是否有在浏览器中混合音频的好方法。一旦用户已经拖动并删除了所有曲目,您可以拥有一个“播放”按钮,如果您愿意,可以通过 HTML5 &lt;audio&gt; 标签触发播放事件。然后,一旦该曲目结束,它就可以触发下一个播放。
    猜你喜欢
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多