功能需求:

一、获取本地音频文件,进行解析成二进制数据音频流

二、将音频流转化成byte[]数组,按指定大小字节数进行分包

三、将音频流分成若干个包,以List列表形式缓存到redis数据库中

四、从redis数据库中获取数据,转换成音频流输出到浏览器播放、实现音频下载功能

程序如下:

1.在SpringBootpom.xml文件中添加Redis依赖

  <!--Redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.在SpringBoot配置文件中添加以下配置

 # 服务端口
server:
port: 8080 spring:
#reids配置
redis:
host: 127.0.0.1 # Redis服务器地址
database: 1 # Redis数据库索引(默认为0)
port: 6379 # Redis服务器连接端口
password: # Redis服务器连接密码(默认为空)
jedis:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 8 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
timeout: 3000ms # 连接超时时间(毫秒)

3.创建RedisTemplate对象操作redis

RedisTemplate介绍:

说的通俗一点…为了让Spring框架体系能够更加方便的接入Redis的功能,RedisTemplate其实就是Spring框架对Jedis的封装…是 spring-data-redis中使用redis的模版。

  /**
* 创建redisTemplate对象操作redis
*/ @Resource
private RedisTemplate<String,Object> redisTemplate;

4.主业务数据处理读取音频文件进行转换存储

通过FileInputStream对象把音频文件转换成byte[]数组,进行分包,把分好包的字节数据添加到List集合中,在调用RedisTemplate对象的opsForList().rightPushAll方法批量添加参数List元素,以Redis的列表数据格式存储。

   /**
* 获取文件将文件转换成byte[]数组,进行分包存储到redis
*/
@RequestMapping("/setAudio")
@ResponseBody
public Object getsty() throws Exception {
File file = new File("E:/zmj-3011-32779/12121.mp3");
FileInputStream inputFile = new FileInputStream(file);
byte[] buffer = new byte[(int) (file.length() * 1)];
inputFile.read(buffer);//文件解析把字节数添加到buffer[]中
inputFile.close(); int viceLength = 180; //每个字节包大小
int viceNumber = (int) Math.ceil(buffer.length /(double) viceLength);//存多少个包
int from, to;
List listrk = new ArrayList();
for (int i=0;i<viceNumber;i++){ //将完整音频buffer[]进行循环拆分
ioentity ioe=new ioentity();
from=(int) (i*viceLength);
to=(int)(from+viceLength);
if(to>buffer.length)
to=buffer.length;
listrk.add(Arrays.copyOfRange(buffer,from,to));//按字节范围拷贝生成新数组,添加到List列表中
}
redisTemplate.opsForList().rightPushAll("Audio", listrk);//redisTemplate的批量添加,以List列表形式进行存储
return "redis入库成功!";
}

redis客户端存储结果:

可以看出只存储了一个key,value是以list列表形式存储,音频文件以180个字节数组进行存储,一共存储了2634个。此处没有设缓存时间,所以不会超时。

6.从Redis数据库缓存中获取音频数据进行解析

通过Redis对象的redisTemplate.opsForList().range方法获取缓存的value,通过list集合接收进行遍历,进行合并生成一个新的byte数组,在通过OutputStream对象输出byte数组,浏览器自动解析二进制音频流文件。

  /**
* 从redis中分包取值进行byte[]数组合并解析音频
*/
@RequestMapping("/getkeyAudio")
public Object getKey(HttpServletResponse response) throws Exception{
OutputStream os = response.getOutputStream();
List list =redisTemplate.opsForList().range("Audio", 0, -1); //通过key获取指定区间的值,List方式存储用List集合去接收 //合并音频
List<byte[]> blist = list;
int lengthTotal = 0;
for (byte[] item : blist) {
lengthTotal += item.length;
}
byte[] totalByte = new byte[lengthTotal];
int begin = 0;
for (byte[] item : blist) {
//System.arraycopy(原数组, 原数组起始位置, 目标数组, 目标数组起始位置, 复制长度);
System.arraycopy(item, 0, totalByte, begin, item.length);
begin += item.length;
}
os.write(totalByte);//通过OutputStream对象输出合并后的数组 return ""; //OutputStream对象输出流,直接返回为空,浏览器自动会为我们解析音频流
}

第一种解析方法:

浏览器发起请求得到音频二进制流,浏览器解析自动生成一个播放器播放该音频及附加下载功能。

第二种解析方法:

在HTML页面中定义Audio标签,创建XMLHttpRequest对象发起请求,通过Audio标签进行解析。

<audio id="sound" width="200" controls="controls"></audio>

<script>
$(document).ready(function(){
agf();
}); function agf() {
//创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
//配置请求方式、请求地址以及是否同步
xhr.open('POST', '/getkey', true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//设置请求结果类型为blob
xhr.responseType = 'blob';
//请求成功回调函数
xhr.onload = function(e) {
if (this.status == 200) {//请求成功
//获取blob对象
var blob = this.response;
//获取blob对象地址,并把值赋给容器
$("#sound").attr("src", URL.createObjectURL(blob));
}
};
xhr.send();
}
</script>

个人总结:

记录点滴每天成长一点点,学习是永无止境的!转载请附原文链接!!!

将音频文件转二进制分包存储到Redis(奇淫技巧操作)的更多相关文章

  1. scrapy各种持久化存储的奇淫技巧

    理论 磁盘文件: 基于终端指令 1)保证parse方法返回一个可迭代类型的对象(存储解析到的页面内容) 2)使用终端指令完成数据存储到指定磁盘文件中的操作,如:scrapy crawl 爬虫文件名称 ...

  2. C语言解析WAV音频文件

    C语言解析WAV音频文件 代码地址: Github : https://github.com/CasterWx/c-wave-master 目录 前言 了解WAV音频文件 什么是二进制文件 WAV的二 ...

  3. 科大讯飞语音转文字,ffmpeg将wav转成pcm二进制音频文件

    百度和讯飞和其他厂都提供了语音识别的接口,这里使用讯飞的识别将本地手机录的音频文件转成文字 以下注意事项: 1.X_Param 参数开始的时候带了空格导致验证不过,原因是讯飞将字符串做了repelce ...

  4. C# 使用FileUpload控件上传图片,将文件转换成二进制进行存储与读取

    状况描述: 需要上传文件,但是不想要保存到实体路径下,便可以用该功能来实现. 效果图: 点击[Upload]按钮,上传文件到数据库: 点击[Preview],预览文件: 具体实现: 前台: <t ...

  5. 获取google翻译的音频文件_合并音频文件的方法

    1. 把引文输入google 翻译,然后点击"朗读"

  6. H5页面实现一个Audio标签加载多个音频文件,并进行播放和展示音频长度

    最近微信项目中有需求,要将微信端发送过来的amr格式的语音文件,在项目中的页面上进行展示和播放,实现方式如下: 1.首先java后台收到微信端的消息推送的时候,使用 ffmpeg将amr格式的音频文件 ...

  7. (原创)speex与wav格式音频文件的互相转换

    我们的司信项目又有了新的需求,就是要做会议室.然而需求却很纠结,要继续按照原来发语音消息那样的形式来实现这个会议的功能,还要实现语音播放的计时,暂停,语音的拼接,还要绘制频谱图等等. 如果是wav,m ...

  8. Windows Phone 8初学者开发—第21部分:永久保存Wav音频文件

    原文 Windows Phone 8初学者开发—第21部分:永久保存Wav音频文件 第21部分:永久保存Wav音频文件 原文地址:http://channel9.msdn.com/Series/Win ...

  9. Windows Phone 8初学者开发—第20部分:录制Wav音频文件

    原文 Windows Phone 8初学者开发—第20部分:录制Wav音频文件 原文地址:http://channel9.msdn.com/Series/Windows-Phone-8-Develop ...

随机推荐

  1. set dict tuple 内置方法

    今日内容 * 元祖及内置方法* 字典及内置方法* 集合及内置方法* 字符编码 元祖tuple 与列表类似可以存多个值,但是不同的是元祖本身不能被修改 ```python一:基本使用:tuple 1 用 ...

  2. 测试同学动手搭个简易web开发项目

    技术栈 node.js, vue.js, axios, python, django, orm, restful api, djangorestframework, mysql, nginx, jen ...

  3. node+ajax实战案例(1)

    1.mysql入门 1.1.数据库相关概念 1.1.1.什么是数据? 描述事物的符号记录称为数据,描述事物的符号可以是数字.文字.声音.图片.视频等,有多种表现形式,都可以经过数字化后存入计算机 1. ...

  4. SpringBoot2.x的依赖管理

    前提 这篇文章是<SpringBoot2.x入门>专辑的第1篇文章,使用的SpringBoot版本为2.3.1.RELEASE,JDK版本为1.8. 主要梳理一下SpringBoot2.x ...

  5. return ,continue,break的用法与区别总结

    1.return 语句的作用 (1) return 从当前的方法中退出,返回到该调用的方法的语句处,继续执行.       (2) return 返回一个值给调用该方法的语句,返回值的数据类型必须与方 ...

  6. P2136 拉近距离

    我也想有这样的爱情故事,可惜我单身 其实这道题就是一个比较裸的最短路问题.对于一个三元组 (S,W,T) ,S其实就是一个端点,而W就是到达的端点,连接两个端点的边长为-T,注意要取一个相反数,这样才 ...

  7. 洛谷 P1194 【买礼物】

    这道题其实就是转化一个模型就可以了. 买了一个另外一个又优惠,其实就相当于在优惠的时候连一条边,因为不可能多买,所以就是建一棵最小生成树.最后因为肯定买了一件物品,要加上最初的单价. 代码: #inc ...

  8. 【vue】---- ElementUI 实现上传Excel

    1.功能描述:vue 项目使用 el-upload 实现上传 Excel. 2.功能效果:在el-upload基础上做了样式整改. 3.功能实现: // el-upload 上传组件 <temp ...

  9. 前端工程化的的理解,浅谈web工程化的开发流程

    1. 什么是前端工程化 自有前端工程师这个称谓以来,前端的发展可谓是日新月异.相比较已经非常成熟的其他领域,前端虽是后起之秀,但其野蛮生长是其他领域不能比的.虽然前端技术飞快发展,但是前端整体的工程生 ...

  10. C++中vector和堆的常用使用方法&例题:数据流中的中位数

    vector常用函数: (1)a.size();//返回a中元素的个数: (2)a.push_back(5);//在a的最后一个向量后插入一个元素,其值为5 (3)a[i]; //返回a的第i个元素, ...