本文包含内容概述:

  • 整理总结的音频相关资料
  • 音频相关jsapi说明及示例
  • vue编写的组件及git项目地址
在线预览:
  • http://123.57.178.145:5007/audio_edit/index.html

目录

    • 在线预览:
  • 标题音频编码、格式(部分)
    • PCM编码
    • APE格式
    • MP3编码、OGG编码
    • MPC编码
    • AAC编码
    • WMA格式
    • RA格式
    • WAV格式
  • 剪辑原理(基础方式)
    • 音频数据
    • 最佳频率44.1kHz
    • 加减速
    • 裁切
    • 拼接
    • 合并
  • JS相关API代码示例
    • 获取audioContext
    • 获取音频arraybuffer
    • arraybuffer(mp3、wav、mp4、ogg等浏览器可识别格式) 转码成 audiobuffer(PCM编码),以便操作数据
    • 创建新的音频createBuffer
    • 合并音频(同时播放两个音频),示例
    • 创建wav音频文件,并填入数据(audiobuffer => wav)
    • audio加载事件
    • audio属性及方法
    • input添加音频
    • 生成audio,并读取音频数据
  • 使用到的编码库
    • mp3 => libmp3lame =>.mp3
    • ogg => libvorbis =>.ogg
    • aac => libfdk_aac =>.mp4
    • wma => wmav1 =>.asf
  • 思路
  • 组件git地址
  • 声明

标题音频编码、格式(部分)

PCM编码

无损编码,模拟波形,占用空间大

APE格式

无损压缩

MP3编码、OGG编码

有损压缩,边读边放

MPC编码

更小的体积更好的音质

AAC编码

又称MPEG-4 AAC,即m4a,
最大能容纳48通道的音轨
高压缩比的音频压缩算法,AAC通常压缩比为18:1

WMA格式

用于网络播放。
可以限制播放时间和播放次数甚至于播放的机器等等。
支持流技术,即边读边放。

RA格式

用于网络播放。
可以根据听众的带宽来控制自己的码率,在保证流畅的前提下尽可能提高音质。
支持边读边放,也同样支持使用特殊协议来隐匿文件的真实网络地址,从而实现只在线播放而不提供下载的欣赏方式。

WAV格式

所有的WAV都有一个文件头,这个文件头包含了音频流的编码参数。
常见的都是PCM编码。
但MP3编码也可以运用在WAV中。

剪辑原理(基础方式)

  • 音频数据

采样率:每秒的采样数量。
采样大小:每次采样的采样精度。
通道数:pcm双声道数据规则为左、右声道轮流记录一个采样。

  • 最佳频率44.1kHz

人耳能够感觉到的最高频率为20kHz,
使得离散信号恢复成连续模拟信号不失真至少要让采样频率为 原始信号的2倍
因此要满足人耳的听觉要求,则需要每秒进行40k次采样

  • 加减速

对音频数据以更高的采样率播放,即可实现加速。减速同理。

  • 裁切

根据采样率计算时间对应数据,截取音频数据

  • 拼接

多个音频,转为相同采样率,拼接音频数据

  • 合并

让两个音频文件的音频数据相加即可

JS相关API代码示例

  • 获取audioContext

非js原生,可在浏览器、node.js使用,小程序不可用

let audioContext = new(window.AudioContext || window.webkitAudioContext)();
  • 获取音频arraybuffer
//方法1.get请求
let res = await this.$ajax.request('GET', url, {}, 'arraybuffer')
//ajax发送GET请求responseType:'arraybuffer'//方法2.input选择文件,FileReader读取文件
inputchange(val){var reader = new FileReader();reader.onload = (e) => {let audiodata={name:val.file.name,arraybuffer:e.target.result}};reader.readAsArrayBuffer(val.file)
}//属性
AudioBuffer.sampleRate 只读
//存储在缓存区的PCM数据的采样率:浮点数,单位为 sample/s。
AudioBuffer.length 只读
//返回存储在缓存区的PCM数据的采样帧率:整形。
AudioBuffer.duration 只读
//返回存储在缓存区的PCM数据的时长:双精度型(单位为秒),。
AudioBuffer.numberOfChannels 只读
//返回存储在缓存区的PCM数据的通道数:整形。//方法
AudioBuffer.getChannelData()
//返回一个 Float32Array,包含了带有频道的PCM数据,由频道参数定义(有0代表第一个频道)
AudioBuffer.copyFromChannel()
//从AudioBuffer的指定频道复制到数组终端。
AudioBuffer.copyToChannel()
//复制样品到原数组的AudioBuffer的指定频道
  • arraybuffer(mp3、wav、mp4、ogg等浏览器可识别格式) 转码成 audiobuffer(PCM编码),以便操作数据
//解码后采样率为计算机所设置的采样率
audioContext.decodeAudioData(arraybuffer, AudioBuffer => {console.log(AudioBuffer)//异步解码音频文件 转为PCM编码的AudioBuffer
});
  • 创建新的音频createBuffer
audioContext.createBuffer(channels, length, sampleRate);//channels:通道数, length:采样数量, sampleRate:采样率
//采样率=采样数量/时长秒数
  • 合并音频(同时播放两个音频),示例
let bufferarr = []; //要合并的音频数组
bufferarr.push(await this.getaudio('http://localhost:8081/static/asd.mp3')
)//加载音频audiobuffer
bufferarr.push(await this.getaudio('http://localhost:8081/static/ass.mp3')
)//加载音频audiobuffer
bufferarr.sort(function (a, b) { //按长度排序return b.duration - a.duration;
});
let channels = 2
sourceNodebuffer = audioContext.createBuffer(channels, bufferarr[0].length, bufferarr[0].sampleRate);//创建音频
for (var channel = 0; channel < channels; channel++) {//循环声道var newbuffer = sourceNodebuffer.getChannelData(channel);for(var key = 0; key < bufferarr.length; key++){//循环音频let buffer = bufferarr[key].getChannelData(channel);for (var i = 0; i < buffer.length; i++) {newbuffer[i] += buffer[i];}}
}
  • 创建wav音频文件,并填入数据(audiobuffer => wav)
getFullWavData(audiobuffer) {//创建wav文件 var sampleRate = audiobuffer.sampleRate;var sampleBits = 16;var bytes = audiobuffer.getChannelData(0);var bytes2 = audiobuffer.getChannelData(1);var dataLength = (bytes.length+bytes2.length) * (sampleBits / 8);var buffer = new ArrayBuffer(44 + dataLength);var data = new DataView(buffer);var offset = 0;var writeString = function(str) {for (var i = 0; i < str.length; i++) {data.setUint8(offset + i, str.charCodeAt(i));}};// 资源交换文件标识符   writeString('RIFF');offset += 4;// 下个地址开始到文件尾总字节数,即文件大小-8   data.setUint32(offset, 36 + dataLength, true);offset += 4;// WAV文件标志  writeString('WAVE');offset += 4;// 波形格式标志   writeString('fmt ');offset += 4;// 过滤字节,一般为 0x10 = 16   data.setUint32(offset, 16, true);offset += 4;// 格式类别 (PCM形式采样数据)   data.setUint16(offset, 1, true);offset += 2;// 通道数   data.setUint16(offset, audiobuffer.numberOfChannels, true);offset += 2;// 采样率,每秒样本数,表示每个通道的播放速度   data.setUint32(offset, sampleRate, true);offset += 4;// 波形数据传输率 (每秒平均字节数) 单声道×每秒数据位数×每样本数据位/8   data.setUint32(offset, audiobuffer.numberOfChannels * sampleRate * (sampleBits / 8), true);offset += 4;// 快数据调整数 采样一次占用字节数 单声道×每样本的数据位数/8   data.setUint16(offset, audiobuffer.numberOfChannels * (sampleBits / 8), true);offset += 2;// 每样本数据位数   data.setUint16(offset, sampleBits, true);offset += 2;// 数据标识符   writeString('data');offset += 4;// 采样数据总数,即数据总大小-44   data.setUint32(offset, dataLength, true);offset += 4;// 写入采样数据   data = this.reshapeWavData(sampleBits, offset, bytes,bytes2, data);let file = new Blob([data], {type: 'audio/wav'});//下载音频var href = URL.createObjectURL(file);const a = document.createElement("a");a.download = "output.mp3";a.href = href;document.body.appendChild(a);a.click();document.body.removeChild(a);
}reshapeWavData(sampleBits, offset, iBytes,iBytes2, oData) { // 写入采样数据,wav左右声道数据交替填入if (sampleBits === 8) {for (var i = 0; i < iBytes.length; i++, offset++) {var s = Math.max(-1, Math.min(1, iBytes[i]));var val = s < 0 ? s * 0x8000 : s * 0x7FFF;val = parseInt(255 / (65535 / (val + 32768)));oData.setInt8(offset, val, true);}} else {for (var i = 0; i < iBytes.length; i++, offset += 4) {var s = Math.max(-1, Math.min(1, iBytes[i]));oData.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);//左声道var s = Math.max(-1, Math.min(1, iBytes2[i]));oData.setInt16(offset+2, s < 0 ? s * 0x8000 : s * 0x7FFF, true);//右声道}}return oData;
}
  • audio加载事件
let audio = new Audio("url");
//音频(视频相同)在加载过程中,触发的顺序如下:
audio.onloadstart //开始加载
audio.ondurationchange //时长发生变化时触发,加载后时长从 "NaN" =>当前时长
audio.onloadedmetadata //时长,尺寸大小(视频),文本轨道,元数据加载后触发
audio.onloadeddata //当前帧的数据加载完成,且还没有足够的数据播放下一帧时触发
audio.onprogress //在浏览器下载指定的音频时触发
audio.oncanplay //在用户可以开始播放音频时触发
audio.oncanplaythrough //音频可以正常播放且无需停顿和缓冲时触发
  • audio属性及方法
//属性
autoplay    设置或返回是否在加载完成后随即播放音频
buffered    返回表示音频已缓冲部分的 TimeRanges 对象
controller  返回表示音频当前媒体控制器的 MediaController 对象
controls    设置或返回音频是否显示控件(比如播放/暂停等)
crossOrigin 设置或返回音频的 CORS 设置
currentSrc  回当前音频的 URL
currentTime 设置或返回音频中的当前播放位置(以秒计)
defaultMuted    设置或返回音频默认是否静音
defaultPlaybackRate 设置或返回音频的默认播放速度
duration    返回当前音频的长度(以秒计)
ended   返回音频的播放是否已结束
error   返回表示音频错误状态的 MediaError 对象
loop    设置或返回音频是否应在结束时重新播放
mediaGroup  设置或返回音频所属的组合(用于连接多个音频元素)
muted   设置或返回音频是否静音
networkState    返回音频的当前网络状态
paused  设置或返回音频是否暂停
playbackRate    设置或返回音频播放的速度
played  返回表示音频已播放部分的 TimeRanges 对象
preload 设置或返回音频是否应该在页面加载后进行加载
readyState  返回音频当前的就绪状态
seekable    返回表示音频可寻址部分的 TimeRanges 对象
seeking 返回用户是否正在音频中进行查找
src 设置或返回音频元素的当前来源
textTracks  返回表示可用文本轨道的 TextTrackList 对象
volume  设置或返回音频的音量//方法
addTextTrack()  在音频中添加一个新的文本轨道
canPlayType()   检查浏览器是否可以播放指定的音频类型
fastSeek()  在音频播放器中指定播放时间。
getStartDate()  返回一个新的Date对象,表示当前时间轴偏移量
load()  重新加载音频元素
play()  开始播放音频
pause() 暂停当前播放的音频
  • input添加音频
addfile(val){var reader = new FileReader();reader.onload = async (e) => {// console.log(e,val)let audio = await this.toaudio(val.file);this.fillarr.push({name:val.file.name,duration:audio.duration,//时长// data : new Uint8Array(e.target.result)buffer:e.target.result});};reader.readAsArrayBuffer(val.file);
},
  • 生成audio,并读取音频数据
toaudio(file){return new Promise((resolve, reject) => {let audio = new Audio(URL.createObjectURL(file));audio.onloadedmetadata = () => {//加载完成后返回audioresolve(audio)}})
},

使用到的编码库

思路

  • 使用worker异步处理音频
  • 使用ffmpeg的asm版,实现音频转码、裁切
  • 操作PCM编码的audiobuffer,实现拼接合成
  • 流程
  1. 输入.mp3|.ogg|.mp4|.asf|.wav
  2. ffmpeg转码裁切 => mp3 => decodeAudioData => pcm(audiobuffer) => 拼接合成 => wav
  3. 编码成指定格式输出文件mp3、ogg、mp4、asf、wav

组件git地址

vue示例git地址:https://gitee.com/xuedongwei/audio_edit.git

//使用简介
import audioedit from '../../static/audio_edit.js';
let audio_edit = new audioedit();
//udio_edit.state: 1,//状态 1等待任务,2正在编译,3正在停止
//audio_edit.progress:0,//进度0-100
//-------------------------------------------------------------------
//音频编辑 audio_edit.edit()
//参数outformat:"mp3",   //选填,输出格式 mp3, ogg, aac, wma, wav,默认mp3outchannel:2,      //选填,输出音频声道数1,2,默认2files:[{name:"asd.mp3",  //必填,音频文件名,原名buffer:buffer,   //必填,音频bufferstoptime:[30,50],//选填,截取-时间s,默认全部inserttime:0,    //选填,插入到-时间s,默认顺延拼接insertchannel:['0,0','1,1'] //选填,通道操作 '0,0','1,1','0,1','1,0' 多选 ex:'0,1'左=>右}]
//返回示例resolve({'code': 200,//成功,输出文件'name': "out.wav",'buffer': arraybuffer});resolve({'code': 400,//失败'message': '失败原因'})//-------------------------------------------------------------------
//格式转换 audio_edit.format()
//参数name:"asd.mp3",    //必填,音频文件名,原名buffer:buffer,     //必填,音频bufferoutformat:"mp3",   //选填,输出格式 mp3, ogg, aac, wma, wav,默认mp3outchannel:2,      //选填,输出音频声道数1,2outsample:44100,   //选填,导出采样率 采样率 11025电话音质 22050广播音质 44100音频CD 48000 96000高清晰度DVDoutbitrate:"128k", //选填,导出比特率 96k、128k、192k、320k
//返回同音频编辑//-------------------------------------------------------------------
//停止工作 audio_edit.stop()//无返回

声明

由于本人水平有限,参考了很多别人的文章、组件,由于时间过长找不到源头,这里就不列出了,还请谅解

web前端-纯前端音频剪辑,vue音频编辑组件相关推荐

  1. Java fx 变速播放音乐_QVE音频剪辑如何调整音频播放速度?音乐变速方法说明

    为了学习的需要,我们经常会在网上下载很多音频文件.可是当我们听的时候,却发现音频的播放速度要么太快了,要么就是太慢了,听起来不舒服.当遇到这样问题时,我们可以用QVE音频剪辑调整音频播放速度.考虑到很 ...

  2. 第三章 添加背景音乐与音频剪辑

    ​第三章 添加背景音乐与音频剪辑 3.1为视频添加音乐的方法 音乐是短视频的重要组成部分之一,一段适合视频的音乐能为视频锦上添花,本节主要讲解添加背景音乐的多种操作方法. 3.1.1给视频添加背景音乐 ...

  3. mac上免费的音频剪辑软件在哪里可以快速下载

    幂果Mac音频剪辑软件是有网幂科技倾情打造的一款免费音乐编辑器,操作简单,音轨可随意拖动.删减,按钮功能明确,新手小白无需花费大量时间也能轻松制作. 幂果Mac音频剪辑软件是一款出色的操作方便的音乐m ...

  4. 幂果支招:哪里找免费的Mac版音频剪辑软件

    一段打动人心的短视频离不开背景音乐或插曲的氛围营造,背景音乐或插曲的编辑离不开一款好用的音频剪辑软件.哪里找免费的Mac版音频剪辑软件?幂果小编来支招. 幂果Mac音频剪辑,音频任意片段一键截取,轻松 ...

  5. Audacity(电脑音频剪辑软件)官方中文版V3.0.2 | 完全免费的音乐制作软件audacity下载

    Audacity 是一款专业易于使用且完全免费的音乐制作软件,高度可定制的界面能实时显示预览,具备多轨音频剪辑和音频录制功能,提供了数十种可修改或自己创建的插件以及无限的撤消和重做能力,能将磁带和唱片 ...

  6. 《UnityAPI.AudioClip音频剪辑》(Yanlz+Unity+SteamVR+云技术+5G+AI+VR云游戏+AudioClip+loadInBackground+立钻哥哥++OK++)

    <UnityAPI.AudioClip音频剪辑> 版本 作者 参与者 完成日期 备注 UnityAPI_AudioClip_V01_1.0 严立钻 2020.05.30 #<Unit ...

  7. 迅捷音频编辑软件 - 多功能的MP3格式转换器附带音频剪辑功能

    音频编辑软件是一种可以针对音频文件进行编辑的音频剪辑软件,音频编辑软件用的最广泛的就是调音师,他们不仅要具备优秀的音质辨别感,同时还需要熟悉各种音频剪辑软件,今天小编要给大家带来的这款音频编辑软件不仅 ...

  8. Ashampoo Music Studio 8(阿香婆音频剪辑软件电脑版)官方中文版V8.0.4 | 音频剪辑软件哪个好用

                            Ashampoo Music Studio 8 是来自德国阿香婆公司重磅开发的一款集封面编辑.音乐库管理.音频提取.播放列表生成.抓取刻录.音频剪辑.音 ...

  9. ffmpeg js转换音频_实践!实现纯前端下的音频剪辑处理

    前言 最近在做一个项目,需要对 webRTC 录制的音频进行处理,包括音频的裁剪.多音频合并,甚至要将某个音频的某一部分替换成另一个音频. 原本笔者打算将这件工作交给服务端去完成,但考虑,其实无论是前 ...

最新文章

  1. golang 不定参 可变参 使用 传递
  2. 缓冲区溢出_了解Java缓冲池
  3. [转]程序员趣味读物:谈谈Unicode编码
  4. hostingranking.cn·基于ghost的轻量技术架构整理
  5. 【控制】多智能体系统总结。1. 系统模型。2.控制目标。3.模型转换。
  6. case when then else多个条件_CentOS「linux」学习笔记24:if和case多个条件判断
  7. Andriod开发技巧——Fragment的懒载入
  8. STM32 IO口输入输出模式的简洁见解
  9. java.lang.UnsatisfiedLinkError: com.jacob.com.D...
  10. C#正则表达式判断输入的是不是数字
  11. from PyQt4 import QtGui,QtCore出错-解
  12. 【Java】浅析八种基本类型
  13. Silverlight 4 初学者的10大经典问答
  14. iOS 52个技巧学习心得笔记 第一章 熟悉OC
  15. 开源OA项目:办公用品如何管理?
  16. 网络驱动之net_device结构体
  17. 我是斗图王之python爬取表情包
  18. html评价标准展示,网页设计评分标准.doc
  19. electron-vue通过配置文件设置baseUrl
  20. 手机web端唤醒qq客户端以及电脑web端唤醒qq客户端

热门文章

  1. oracle中md5算法,oracle数据库中存储过程使用MD5算法加密
  2. 中科大2021计算机考研分数线,中国科学技术大学2021年考研复试各科分数线_中国科大考多少分能进复试-聚创中国科大考研网...
  3. 帆软报表决策系统忘记密码重置
  4. php地区代码吗,将国家/地区名称转换为国家/地区代码缩写php
  5. 多級commentable處理
  6. 联想android电视软件下载,联想智能电视如何通过浏览器来下载第三方应用软件...
  7. 编写计算机程序的几个步骤,第1讲程序设计的一般步骤ok.doc
  8. ElasticSearch中Transient与Persistent的区别
  9. 反距离加权法IDW C#实现
  10. python2.7的字符串拼接