java silk v3 转码,小程序、录音、TP5、转码、silk
本篇文章主要介绍一下以下功能:
用小程序实现录音功能,在本地播放,提交服务端,服务端播放。
中间遇到了一些坑,找到了一些解决方法,如果有更优的解决方案希望你能在评论留言,一起加油。
1.小程序端
前端展示页面,小程序采用数据绑定方式,这里正在录音和正在播放的状态切换,用两张图根据录音状态和播放状态切换,这里就不多说了。
长按开始录音,触发录音事件,松手执行录音结束,将录音结果保存在本地。
/**
* 开始录音
*/
startRecord: function () {
var that = this
that.setData({
isRecording: true,
});
whisper.startRecord({
success(result) {
that.setData({
isRecording: false,
});
console.log('录音成功:', result);
console.log('录音成功:', result.tempFilePath);
//提交录音
var src = result.tempFilePath;
var name = 'record'
repair.uploadRecord(src, name, (res) => {
that.data.recordObj.record = res;
});
},
fail(error) {
console.log('录音失败:', error);
},
process() {
that.setData({
duration: whisper.getRecordDuration(),
});
},
compelete() {
},
});
},
/**
* 停止录音
*/
stopRecord: function () {
var that = this;
whisper.stopRecord({
success(result) {
that.setData({
isRecording: false,
});
console.log('停止录音:', result);
},
fail(error) {
console.log('停止录音失败:', error);
}
});
},
/**
* 播放录音
*/
play: function () {
var that = this
that.setData({
isPlaying: true,
});
whisper.playRecord({
src: whisper.getRecordSrc(),
success(result) {
that.setData({
isPlaying: false,
});
console.log('播放/暂停成功:', result);
},
fail(error) {
that.setData({
isPlaying: false,
});
console.log('播放/暂停失败:', error);
}
});
},
在录音结束后,执行success的回调函数,上传录音文件到服务器,注意微信小程序的录音文件是silk格式,这是一大坑,在服务端需要处理一下,后面再说。
具体的上传在model层。
//上传录音
uploadRecord(src, name, callback){
var params = {
url:'repair/record',
filePath: src,
name: name,
formData: {
'name': name
},
sCallback: function (data) {
callback && callback(data);
}
};
this.upload(params);
}
录音类也贴一下
var noop = function noop() { };
var recorder = {
};
/***
* @class
* 表示请求过程中发生的异常
*/
var RecordError = (function () {
function RecordError(message) {
Error.call(this, message);
this.message = message;
}
RecordError.prototype = new Error();
RecordError.prototype.constructor = RecordError;
return RecordError;
})();
function startRecord(options) {
if (typeof options !== 'object') {
var message = '请求传参应为 object 类型,但实际传了 ' + (typeof options) + ' 类型';
throw new RecordError(message);
}
var process = options.process;
var success = options.success || noop;
var fail = options.fail || noop;
var complete = options.complete || noop;
if (typeof process !== 'function') {
var message = '刷新Ui函数不存在';
throw new RecordError(message);
}
// 成功回调
var callSuccess = function () {
success.apply(null, arguments);
complete.apply(null, arguments);
};
// 失败回调
var callFail = function (error) {
fail.call(null, error);
complete.call(null, error);
};
// 初始化录音器
initRecorder();
// 实际进行请求的方法
doRecord();
// 实际进行请求的方法
function doRecord() {
console.log("开始录音")
recorder.timer = setInterval(function () {
recorder.duration += 1;
process();
if (recorder.duration >= recorder.maxDuration && recorder.timer) {
clearInterval(recorder.timer);
}
}, 1000);
wx.startRecord({
success: function (res) {
if (res.tempFilePath) {
recorder.src = res.tempFilePath;
callSuccess.apply(null, arguments);
return ;
} else {
message = '录音文件保存失败';
var error = new RecordError(message);
options.fail(error);
}
callFail(error);
},
fail: callFail,
complete: complete,
});
};
// 初始化录音器
function initRecorder() {
recorder = {
maxDuration: 60,
duration: 0,
src: null,
timer: null,
};
}
};
function stopRecord(options) {
if (typeof options !== 'object') {
var message = '请求传参应为 object 类型,但实际传了 ' + (typeof options) + ' 类型';
throw new RecordError(message);
}
var success = options.success || noop;
var fail = options.fail || noop;
var complete = options.complete || noop;
// 成功回调
var callSuccess = function () {
success.apply(null, arguments);
complete.apply(null, arguments);
};
// 失败回调
var callFail = function (error) {
fail.call(null, error);
complete.call(null, error);
};
doStopRecord();
// 实际进行请求的方法
function doStopRecord() {
wx.stopRecord({
success: function (res) {
if (recorder.timer) {
clearInterval(recorder.timer);
}
callSuccess.apply(null, arguments);
},
fail: callFail,
complete: complete,
});
};
};
function getRecordDuration() {
return recorder.duration || 0;
}
function getRecordSrc() {
return recorder.src || null;
}
module.exports = {
RecordError: RecordError,
startRecord: startRecord,
stopRecord: stopRecord,
getRecordDuration: getRecordDuration,
getRecordSrc: getRecordSrc,
};
播放类
var noop = function noop() { };
var player = {
src: null,
};
/***
* @class
* 表示请求过程中发生的异常
*/
var PlayError = (function () {
function PlayError(message) {
Error.call(this, message);
this.message = message;
}
PlayError.prototype = new Error();
PlayError.prototype.constructor = PlayError;
return PlayError;
})();
function play(options) {
if (typeof options !== 'object') {
var message = '请求传参应为 object 类型,但实际传了 ' + (typeof options) + ' 类型';
throw new PlayError(message);
}
if (!options.src) {
var message = '无资源';
var error = new PlayError(message);
options.fail(error);
return;
}
var process = options.process || noop;
var success = options.success || noop;
var fail = options.fail || noop;
var complete = options.complete || noop;
// 成功回调
var callSuccess = function () {
success.apply(null, arguments);
complete.apply(null, arguments);
};
// 失败回调
var callFail = function (error) {
fail.call(null, error);
complete.call(null, error);
};
if (!player.src || player.src != options.src) {
if (player.src) {
doStop(false);
}
doPlay();
} else {
doStop(true);
}
// 实际进行请求的方法
function doPlay() {
player.src = options.src;
console.log("开始播放" + player.src);
wx.playVoice({
filePath: player.src,
success: function (res) {
// success
console.log("播放结束" + player.src);
player.src = null,
callSuccess.apply(null, arguments);
},
fail: callFail,
complete: complete,
})
};
// 实际进行请求的方法
function doStop(isCallbackOn) {
wx.stopVoice({
success: function () {
console.log("停止播放" + player.src);
player.src = null;
isCallbackOn ? callSuccess.apply(null, arguments) : noop();
},
fail: isCallbackOn ? callFail : noop,
complete: isCallbackOn ? complete : noop,
});
};
};
module.exports = {
PlayError: PlayError,
playRecord: play,
};
ok,前端完成,转向服务端
2.服务端
后端用的是PHP的TP5框架,接收到的silk文件想要在浏览器上播放,我刚开始是想的转码MP3,在网上找了些资料,基本都指向了kn007大神的博客,写了个demo,Silk v3编码格式转码MP3终于实现了,结果发现小程序的silk不是silk V3,哭晕在厕所,这里可能有我没理解的,有人实现了希望可以留言。
然后,我一同事提醒我webm格式的可以直接播放的,囧。那就没的说了,直接base64解码成webm格式。
/**
* 报修录音
* @url /repair/record
* @http post
*/
public function uploadRecord()
{
$name = input('post.name');
if($_FILES[$name]["error"] > 0){
throw new Exception("Error: " . $_FILES[$name]["error"]);
}else{
$file = request()->file($name);
$info = $file->move(ROOT_PATH . 'public' . DS . 'record/'.$this->mainID);
$path = $info->getSaveName();
$base = ROOT_PATH . 'public' . DS;
$silk = $base . 'record/' . $this->mainID . '/' . $path;
$webm = str_replace("silk","webm",$silk);
$returnWebm = str_replace("silk","webm",$path);
$content = file_get_contents($silk);
$baseSilk = base64_decode(str_replace("data:audio/webm;base64,", '', $content));
file_put_contents($webm,$baseSilk);
}
return $returnWebm;
}
也贴一下wins环境下,用silk_v3_decoder.exe转码MP3的测试代码吧,具体的可以看下kn007大神的博客。
public function test()
{
$base = ROOT_PATH . 'public' . DS;
$file = $base.'record\\song1.silk';
$type = $base.'record\\song.pcm';
$res = $base.'record\\song.mp3';
$cmd = "{$base}silk\\windows\\silk_v3_decoder.exe $file $type" ;
exec($cmd, $out);
$cmd1 = "{$base}silk\\windows\\ffmpeg.exe -y -f s16le -ar 24000 -ac 1 -i $type $res";
exec($cmd1,$out1);
}
就这吧。
java silk v3 转码,小程序、录音、TP5、转码、silk相关推荐
- 计算机毕业设计Java智慧防疫上报系统小程序端(源码+系统+mysql数据库+Lw文档)
计算机毕业设计Java智慧防疫上报系统小程序端(源码+系统+mysql数据库+Lw文档) 计算机毕业设计Java智慧防疫上报系统小程序端(源码+系统+mysql数据库+Lw文档) 项目架构:B/S架构 ...
- 闲来无事,用java写了一个魔方小程序。附源码
闲来无事,用java写了一个魔方小程序.附源码 使用三维数组.相对来说还是简单.呵呵. import java.util.ArrayList; import java.util.List; impor ...
- java实现魔方_闲来无事,用java写了一个魔方小程序。附源码 | 学步园
闲来无事,用java写了一个魔方小程序.附源码 使用三维数组.相对来说还是简单.呵呵. import java.util.ArrayList; import java.util.List; impor ...
- 计算机毕业设计Java信用卡增值业务系统小程序管理端(源码+系统+mysql数据库+lw文档
计算机毕业设计Java信用卡增值业务系统小程序管理端(源码+系统+mysql数据库+lw文档 计算机毕业设计Java信用卡增值业务系统小程序管理端(源码+系统+mysql数据库+lw文档) 本源码技术 ...
- java silk转mp3_微信小程序录音文件格式silk遇到的问题及解决方法
不好意思,误导大家了,这种将silk解密的方式只是在小程序测试的时候可以,上线以后这种方法是不行的,还是需要使用解密转码.参见:https://github.com/kn007/silk-v3-dec ...
- php silk v3 decoder,微信小程序语音搜索踩坑:silk文件格式转换,在PHP中使用
直接调用微信小程序录音接口,然后上传到服务器,百度语音的接口是识别不了这种格式的文件,那么问题来了 一.如何转码?ffmpeg? 二.如何在PHP中使用? 本文将要解决这两个问题. 用到的第三方工具: ...
- 芝麻动态码-小程序动态二维码生成
小程序的二维码,是静态的,在公众号里传播的时候,效果不太好,但是因为小程序的logo 很大,可以容纳很多的内容,所以就希望中间的部分可以动态显示. 经过我们的验证,是可行的,来几张效果图 1. 二次元 ...
- 收款码合并有什么弊端_合并收款码小程序,合并收款码助手
之前就发了支付宝和微信的收款码合并,我以为上次教程很简单应该都会制作,不料还是有不少人不会做.这次新增QQ收款码合并,同时也把教程写的更加详细希望大家喜欢哈. 点击下方小程序开始合成制作 ↓↓↓↓ 常 ...
- 啦啦外卖公众号+小程序 V43.0开源至尊独立版+独家用户授权升级+小程序端+APP源码+小程序端VUE源码安装教程
啦啦外卖跑腿平台开源至尊独立稳定版公众号+小程序 V43.0版系统为独立开源版,最大优势全开源,使用的都知道该系统功能非常强大,是目前外卖平台功能最全的一套系统.拿来即用,也非常合适做二开的朋友,包括 ...
- 微信小程序录音 第一篇 (基于微信小程序及百度AI的 人员语音识别转文字显示小程序)
基于微信小程序及百度AI的 人员语音识别转文字显示小程序 基于微信小程序及百度AI的 人员语音识别转文字显示小程序主要分3篇 1.微信小程序录音篇(小程序基于wx.startRecord()微信语音录 ...
最新文章
- SVD(奇异值分解)小结
- Android studio下将项目代码上传至github包括更新,同步,创建依赖
- andoid 打包短信发送到gmail邮箱
- Perl迎来25岁生日
- 提高SQL执行效率的几点建议
- 使用Power Designer(PD)创建数据库模型、数据库表
- 什么作用计算机辅助工艺,什么是CAPP技术(计算机辅助工艺过程设计)
- 【SQLMap工具-1】SQLMap简介及简单应用实例
- 后端日志【22】:时间过的很快,坚持的第7.3个月过去了,我有什么变化?
- 腾讯微博开放平台开发吐槽
- 小米便签产品级的源码
- 2020年度中职组“网络空间安全”赛项xx市竞赛任务书
- 基于51单片机的电子密码锁设计
- 让数据快速使用, “无代码”新贵Nextion BI高效解决企业“BI”难
- java图片加文字水印_JAVA实现图片的修改,添加文字水印效果
- 为你描绘精确的太极图
- 29. 人类将如何变革--走出金字塔模型(上)
- autojs微博_autojs使用intent打开新浪微博的用户任务中心scheme的详细过程
- 如何开源,决定于对开源的认识 ———— 《OpenSources:来自开源革命的呼声》书评...
- iPhone手机查找朋友怎么用?添加对方号码,瞬间变成追踪器
热门文章
- 建设网站-个人电子图书馆
- NFS(网络文件系统)
- 使用 sudo nautilus 进入ubuntu 文件管理器。可以随意复制,删除,粘贴,无权限限制
- VB.NET CHART
- 11 wifi 驱动 进阶 http://blog.csdn.net/wh_19910525/article/details/7393615
- owc报表控件 数据透视表_将数据透视图标题链接到报表过滤器
- Oracle GoldenGate 典型应用场景
- java 获取一天零点零分零秒时间戳
- 2021-07-05 Ubuntu18安装Caffe-ssd with GPU并运行Apollo mutitask yolo3d
- 浅谈设计模式之单例模式