前言
断点上传功能在移动应用中较为常见,使用过程中,要求录制较为清晰切大小适中的语音文件,能够控制断点上传会有较好的用户体验, 下面是我在这方面的一些实践经验,分享一下,不成熟的地方欢迎指正!
混合应用中的音频录制
首先创建一个Cordova项目:
cordova create Audio com.delaware.AudioDemo AudioDemo
cd Audio
cordova platform add ios
cordova platform add android
添加语音功能插件:
cordova plugin add cordova-media-with-compression
采用的音频格式为MPEG4, MPEG4是一个影音串流视讯压缩技术及商业标准格式,MPEG4之优势在于其压缩比(最大可达4000:1),低位元速率,较少之核心程式空间,加强运算功能,及强大之通讯应用整合能力,己成为影音数位视讯产业,最重要之功及标准格式, 后缀名字为.m4a
利用插件可以合理进行图片,比如可以设置压缩码率等等,具体方案我们看一实现代码:
录音:
// Record audio with compression
//
function recordCompressedAudio() {
var src = "myrecording.m4a";
var mediaRec = new Media(src,
// success callback
function() {
console.log("recordCompressedAudio():Audio Success");
},
// error callback
function(err) {
console.log("recordCompressedAudio():Audio Error: "+ err.code);
});
// Record MPEG compressed audio, single channel at 16kHz
var options = {
SampleRate: 16000,
NumberOfChannels: 1
}
mediaRec.startRecordWithCompression(options);
}
停止录制:
media.pauseRecord();
播放:(想要播放一个文件,需要先把录音release掉,否则无法播放)
// Play audio
//
function playAudio(url) {
// Play the audio file at url
var my_media = new Media(url,
// success callback
function() {
console.log("playAudio():Audio Success");
},
// error callback
function(err) {
console.log("playAudio():Audio Error: "+err);
}
);
// Play audio
my_media.play();
// Pause after 10 seconds
setTimeout(function() {
my_media.stop();
}, 10000);
}
对于音频文件录制,需要建一个标准文件夹用于管理文件位置,方便。
这里我们用到插件:
cordova plugin add cordova-plugin-file
定义一个文件夹:
fileSystem.root.getDirectory("MyApp", {create: true}, gotDir);
function gotDir(dirEntry) {
dirEntry.getFile(escape(fileName).replace(/%/g, ''), {create: true, exclusive: false}, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
$timeout(function(){
fileEntry.getMetadata(function(data){
if(data.size === 0){
fileUrl = fileEntry.toURL();
}else{
fileUrl = fileEntry.toURL();
}
},function(){
fileUrl = fileEntry.toURL();
});
},200);
}
判断文件是否存在,没有的话,进行创建操作。
音频文件断点上传
文件上传操作
优点:
1.传输数据为字节级,传输数据可自定义,数据量小。相应的移动端开发,手机费用低
2.传输数据时间短,性能高
3.适合C/S之间信息实时交互
4.可以加密,数据安全性高
缺点:
1.需要对传输的数据进行解析,转化为应用级的数据
2.对开发人员的开发水平要求高
3.相对于Http协议传输,增加了开发量
Http请求主要有http协议,基于http协议的soap协议,常见的http数据请求方式有get和post,web服务
优点:
1.基于应用级的接口使用方便
2.要求的开发水平不高,容错性强
缺点:
1.传输速度慢,数据包大。
2.如实现实时交互,服务器性能压力大
3.数据传输安全性差
Socket适用场景:大文件上传,网络游戏,银行交互,支付。
这里有Android为例:
try {
uploadbar.setMax((int)uploadFile.length());
String souceid = logService.getBindId(uploadFile);
String head = "Content-Length="+ uploadFile.length() + ";filename="+ uploadFile.getName() + ";sourceid="+
(souceid==null? "" : souceid)+"\r\n";
Socket socket = new Socket("172.19.34.69",7878);
OutputStream outStream = socket.getOutputStream();
outStream.write(head.getBytes());
PushbackInputStream inStream = new PushbackInputStream(socket.getInputStream());
String response = StreamTool.readLine(inStream);
String[] items = response.split(";");
String responseid = items[0].substring(items[0].indexOf("=")+1);
String position = items[1].substring(items[1].indexOf("=")+1);
if(souceid==null){
logService.save(responseid, uploadFile);
}
RandomAccessFile fileOutStream = new RandomAccessFile(uploadFile, "r");
fileOutStream.seek(Integer.valueOf(position));
byte[] buffer = new byte[1024];
int len = -1;
int length = Integer.valueOf(position);
while(start&&(len = fileOutStream.read(buffer)) != -1){
outStream.write(buffer, 0, len);
length += len;
Message msg = new Message();
msg.getData().putInt("size", length);
handler.sendMessage(msg);
}
fileOutStream.close();
outStream.close();
inStream.close();
socket.close();
if(length==uploadFile.length()) logService.delete(uploadFile);
} catch (Exception e) {
e.printStackTrace();
}
在Android中除了通过http协议上传小文件外,还可以通过Socket上传较大的文件
案例具体思路:
文件被第一次上传时发送: “Content-Length=”+ uploadFile.length() + “;filename=”+ uploadFile.getName() + “;sourceid=”+null+”\r\n”;字段给服务器
服务器收到字段后,看到文件的sourceid字段值为空,则表示该文件第一次上传,服务器就会自动为其创建id,并且在本地根据文件名建立相应文件用于接收文件数据,同时把该文件路径和id保存在Map集合中,并发送:“sourceid=”+ id+ “;position=0\r\n”;内容给客户端,客户端收到服务器为其创建的id和应该从上传文件的什么位置开始读取信息后,在SQLite数据库中记录下本次上传文件的id和文件路径,然后上传文件。
服务器端则开始接收从客户端发来的数据并保存起来,并且时刻把该文件的上传的数据大小保存在以该文件命名的.log文件中。
当在发送的的时候突然关机或网络出现状况,当再次上传该文件时,客户端就会从SQLite中根据文件路径查找到已上传文件的id,然后发送内容给服务器端,服务器从发来的sourceid字段中读到了数据,就从map集合中找到该文件路径,然后根据路径和文件名找到.log文件,并从中读取上次上传文件的大小发送给客户端,客户端得到后遍选择从文件的指定文件读取上传,服务器则再次接收并从文件指定位置保存。
Socket套接字原理分析
建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
服务器监听:
服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
客户端请求:
指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连接确认:
当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
参考文献:http://www.voidcn.com/article/p-krnvppbl-nh.html
http://www.voidcn.com/article/p-uyyqryjb-yo.html