啊,看着那个标题,你可能会想,“这在科尔多瓦肯定是一件简单的事情,而且肯定是雷蒙德,再一次,写博客是非常明显和简单的,只是为了把人们带到他的 亚马逊愿望清单 上。”是的,我也是这么想的。这个周末我开始为我儿子开发一个简单的小科尔多瓦应用程序。我认为这也会是一篇很棒的博文。但是在处理它时,我遇到了一个录音问题,这让我疯狂了几个小时,所以我想我最好分享一下,这样其他人就不必再用头撞墙了。
因为这个问题变成了一个皇家集群——你知道吗,我决定在这里详细地写博客,并在本周晚些时候讨论应用程序本身。现在,考虑这个用例:
“你想让用户录音。稍后,用户可以播放该录音。”
简单吧?所以我开始研究一种可以让用户进行录音并为其命名的表格。我希望他们能够录制并回放以确保他们喜欢它。
单击记录会触发对媒体捕获插件的调用:
var captureerror = function(e) {
console.log('captureerror' ,e);
}
var capturesuccess = function(e) {
console.log('capturesuccess');console.dir(e);
$scope.sound.file = e[0].localurl;
$scope.sound.filepath = e[0].fullpath;
}
$scope.record = function() {
navigator.device.capture.captureaudio(
capturesuccess,captureerror,{duration:10});
}
这是此处的样板媒体捕获用法。我将 url 和文件路径都存储在 $scope 中,以便稍后保存。播放功能也很简单:
var captureerror = function(e) {
console.log('captureerror' ,e);
}
var capturesuccess = function(e) {
console.log('capturesuccess');console.dir(e);
$scope.sound.file = e[0].localurl;
$scope.sound.filepath = e[0].fullpath;
}
$scope.record = function() {
navigator.device.capture.captureaudio(
capturesuccess,captureerror,{duration:10});
}
这在 android 和 ios 中运行良好。但我注意到一些奇怪的事情。当我在 capturesuccess 中查看媒体捕获对象时,我在 android 中看到了这个:
看到我叫出来的部分了吗?执着的。凉爽的。这给了我温暖的绒毛。然而,在 ios 中,我看到了这个:
如您所见,它被存储在一个临时位置,这是不好的。不幸的是,媒体捕获插件中没有任何内容可以更改以修改此行为。因此——答案很明确。
文件系统!
所以从理论上讲,这应该很容易。首先,我们选择一个涵盖 android 和 ios 的持久位置。文件插件提供了这样一个别名:
cordova.file.datadirectory
我们有一个文件夹,对吧?所以实际上我们需要做的就是将文件从一个位置复制到另一个位置。复制。该死。文件。
但我们有一个问题。首先,我们必须给文件一个唯一的名称。为了处理这个问题,我只用了时间和现有的扩展。
var captureerror = function(e) {
console.log('captureerror' ,e);
}
var capturesuccess = function(e) {
console.log('capturesuccess');console.dir(e);
$scope.sound.file = e[0].localurl;
$scope.sound.filepath = e[0].fullpath;
}
$scope.record = function() {
navigator.device.capture.captureaudio(
capturesuccess,captureerror,{duration:10});
}
然后我花了大约一个小时试图让复制命令工作。我首先添加了大量带有 f 字样的 console.log 消息。如果您不知道这个词是什么,请问您的青少年。我认为有了文件路径,我可以这样做:
var captureerror = function(e) {
console.log('captureerror' ,e);
}
var capturesuccess = function(e) {
console.log('capturesuccess');console.dir(e);
$scope.sound.file = e[0].localurl;
$scope.sound.filepath = e[0].fullpath;
}
$scope.record = function() {
navigator.device.capture.captureaudio(
capturesuccess,captureerror,{duration:10});
}
但是,不,那太容易了。您需要先使用
window.resolvelocalfilesystemurl
。由于文件复制命令需要路径,因此您必须执行两次。这是我最终得到的代码。我删除了一些可能会冒犯某些读者的 console.log 消息。如果你好奇的话,我
不仅仅是
说脏话。
var captureerror = function(e) {
console.log('captureerror' ,e);
}
var capturesuccess = function(e) {
console.log('capturesuccess');console.dir(e);
$scope.sound.file = e[0].localurl;
$scope.sound.filepath = e[0].fullpath;
}
$scope.record = function() {
navigator.device.capture.captureaudio(
capturesuccess,captureerror,{duration:10});
}
总而言之,还不错。一些嵌套的回调,几乎一半的代码都与我的应用程序有关,而不是实际问题,我花了一些时间才到达那里。
幸运的是,一切都很完美。
所以在这一点上,我已经保存了我的音频文件的位置,所以我可以在媒体 api 中使用它,但新位置不再适用于媒体插件。为什么?我不知道。我去年 写了 一篇关于当你使用媒体插件和相对路径时,你必须在 android 上做一些时髦的事情的博客,基本上是在你的相对 url 前加上前缀。就我而言,我使用的是 file:// url,我只是假设它会起作用。
这就是事情变得很棒的地方——它在 android 上运行得很好,但在 ios 上却不行。因为——原因。我在 cordova slack 频道上提出了这个问题,@purplecabbage 提到相对路径可能有效。在我的开发工具中,我尝试通过控制台手动创建媒体对象。我发现——给定文件名——我可以通过将其用作根目录来使用媒体插件访问该文件:
"../library/nocloud/"
。
所以现在我的播放代码如下所示:
var captureerror = function(e) {
console.log('captureerror' ,e);
}
var capturesuccess = function(e) {
console.log('capturesuccess');console.dir(e);
$scope.sound.file = e[0].localurl;
$scope.sound.filepath = e[0].fullpath;
}
$scope.record = function() {
navigator.device.capture.captureaudio(
capturesuccess,captureerror,{duration:10});
}
嗯是的。就是这样。我的应用程序现在可以使用了。我可以录制和测试音频,并且可以将其保存到永久文件系统中。正如我所说,我将在本周晚些时候分享真正的应用程序。