В настоящее время я использую два плагина в моем приложении Nativescript для Android, это
nativescript-audio для записи звука и AndroidAudioConverter для преобразования звука в формат .wav. Проблема заключается в том, что после преобразования аудиофайла в context при потере Android метод getSystemService (просто иногда) и когда я записываю другое аудио и пытаюсь воспроизвести его, не звучит. После преобразования звука, если я закрываю приложение, я получаю несколько ошибок.
Эта ошибка при попытке воспроизвести аудио после преобразования звука
error playFromFile TypeError: ctx.getSystemService is not a function
Когда я играю, если я не конвертирую аудио, этого не происходит.
Эта ошибка возникает, когда я нажимаю кнопку «Назад» для выхода из приложения или выключения приложения в фоновом режиме после преобразования звука:
System.err: java.lang.RuntimeException: Unable to stop activity {xxxxxxxx/com.tns.NativeScriptActivity}: com.tns.NativeScriptException:
System.err: Calling js method onStop failed
System.err: TypeError: getApplication(...).getApplicationContext is not a function
System.err: File: "file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/utils/utils.js, line: 59, column: 50
System.err: StackTrace:
System.err: Frame: function:'getApplicationContext', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/utils/utils.js', line: 59, column: 51
System.err: Frame: function:'getInputMethodManager', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/utils/utils.js', line: 87, column: 34
System.err: Frame: function:'dismissSoftInput', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/utils/utils.js', line: 100, column: 28
System.err: Frame: function:'EditableTextBase.dismissSoftInput', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/editable-text-base/editable-text-base.js', line: 147, column: 20
System.err: Frame: function:'EditableTextBase.onUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/editable-text-base/editable-text-base.js', line: 139, column: 14
System.err: Frame: function:'', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 315, column: 92
System.err: Frame: function:'ViewBase.callFunctionWithSuper', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 304, column: 9
System.err: Frame: function:'ViewBase.callUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 315, column: 14
System.err: Frame: function:'ViewBase.unloadView', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 444, column: 18
System.err: Frame: function:'', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 246, column: 19
System.err: Frame: function:'LayoutBaseCommon.eachChildView', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/layouts/layout-base-common.js', line: 125, column: 26
System.err: Frame: function:'ViewCommon.eachChild', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view/view-common.js', line: 868, column: 14
System.err: Frame: function:'ViewBase.onUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 245, column: 14
System.err: Frame: function:'View.onUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view/view.js', line: 235, column: 37
System.err: Frame: function:'', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 315, column: 92
System.err: Frame: function:'ViewBase.callFunctionWithSuper', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 304, column: 9
System.err: Frame: function:'ViewBase.callUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 315, column: 14
System.err: Frame: function:'ViewBase.unloadView', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 444, column: 18
System.err: Frame: function:'', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 246, column: 19
System.err: Frame: function:'ContentView.eachChildView', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/content-view/content-view.js', line: 70, column: 13
System.err: Frame: function:'PageBase.eachChildView', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/page/page-common.js', line: 120, column: 40
System.err: Frame: function:'ViewCommon.eachChild', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view/view-common.js', line: 868, column: 14
System.err: Frame: function:'ViewBase.onUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 245, column: 14
System.err: Frame: function:'View.onUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view/view.js', line: 235, column: 37
System.err: Frame: function:'', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 315, column: 92
System.err: Frame: function:'ViewBase.callFunctionWithSuper', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 304, column: 9
System.err: Frame: function:'ViewBase.callUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 315, column: 14
System.err: Frame: function:'ViewBase.unloadView', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 444, column: 18
System.err: Frame: function:'', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 246, column: 19
System.err: Frame: function:'FrameBase.eachChildView', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/frame/frame-common.js', line: 368, column: 13
System.err: Frame: function:'ViewCommon.eachChild', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view/view-common.js', line: 868, column: 14
System.err: Frame: function:'ViewBase.onUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 245, column: 14
System.err: Frame: function:'View.onUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view/view.js', line: 235, column: 37
System.err: Frame: function:'Frame.onUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/frame/frame.js', line: 158, column: 37
System.err: Frame: function:'', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 315, column: 92
System.err: Frame: function:'ViewBase.callFunctionWithSuper', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 304, column: 9
System.err: Frame: function:'ViewBase.callUnloaded', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/core/view-base/view-base.js', line: 315, column: 14
System.err: Frame: function:'ActivityCallbacksImplementation.onStop', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/frame/frame.js', line: 780, column: 22
System.err: Frame: function:'NativeScriptActivity.onStop', file:'file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/ui/frame/activity.js', line: 33, column: 25
System.err: at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3816)
System.err: at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3870)
System.err: at android.app.ActivityThread.-wrap5(ActivityThread.java)
System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1408)
System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
System.err: at android.os.Looper.loop(Looper.java:148)
System.err: at android.app.ActivityThread.main(ActivityThread.java:5443)
System.err: at java.lang.reflect.Method.invoke(Native Method)
System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
System.err: Caused by: com.tns.NativeScriptException:
System.err: Calling js method onStop failed
System.err: TypeError: getApplication(...).getApplicationContext is not a function
System.err: File: "file:///data/data/xxxxxxxx/files/app/tns_modules/tns-core-modules/utils/utils.js, line: 59, column: 50
System.err: StackTrace:
System.err:
Чтобы установить AndroidAudioConverter, я создаю плагин с такими зависимостями в файле Gradle:
repositories {
maven {
url "https://jitpack.io"
}
}
dependencies {
compile 'com.google.android.gms:play-services-base:15.0.1'
compile 'com.github.adrielcafe:AndroidAudioConverter:0.0.8'
}
Для записи аудио я использую этот код:
const recorder = new audio.TNSRecorder();
const player = new audio.TNSPlayer();
_recordAudio: function () {
console.log("_recordAudio")
var ext = ".m4a"
_this = this
var path = audioFolder.path + "/audio" + new Date().getMilliseconds() + ext;
_this.RECORDING_PATH = path
return new Promise(function (resolve, reject) {
var androidFormat = null;
var androidEncoder = null;
if (platform.isAndroid) {
androidFormat = 2;
androidEncoder = 3;
}
var recorderOptions = {
filename: path,
format: androidFormat,
bitRate: 24000,
source: 1,
encoder: androidEncoder,
sampleRate: 16000,
metering: false,
infoCallback: function (audio) {
console.log("infoCallback recordAudio");
},
errorCallback: function (err) {
console.log("errorCallback recordAudio");
alert("Error recording.", err);
}
};
recorder.start(recorderOptions).then(function (audio) {
console.log("recorder.start");
return resolve(audio);
},function(err){
return reject(err)
})
});
}
Для конвертации аудио я использую этот код: ПРАВИЛЬНО ДЛЯ РЕАЛИЗОВАННЫХ ИНТЕРФЕЙСОВ
convertMp4ToWav: function (filePath) {
var _this = this
return new Promise(function (resolve, reject) {
var result = {
code: -1,
message: ""
}
var cleanPromiseVariablesAndroid = function () {
_this.resolveConvertMp4ToWav = null
_this.rejectConvertMp4ToWav = null
_this.file = null
}
_this.resolveConvertMp4ToWav = resolve
_this.rejectConvertMp4ToWav = reject
if (!filePath || typeof filePath != "string") {
result.message = "No input file"
return reject(result)
}
var file = new java.io.File(filePath)
_this.file = file
var context = _this.getAndroidContext()
if (!context) {
result.message = "Error converting file"
return reject(result)
}
var IConvertCallback = cafe.adriel.androidaudioconverter.callback.IConvertCallback.extend({
onSuccess: function (fileCoverted) {
try {
console.log("callbackConvert onSuccess")
var newPath = fileCoverted.getPath()
result.code = 1
result.path = newPath
result.message = "File converted"
_this.resolveConvertMp4ToWav(result)
cleanPromiseVariablesAndroid();
return
} catch (e) {
console.log("callbackConvert catch")
console.error(e);
result.message = "Error converting file"
_this.rejectConvertMp4ToWav(result)
cleanPromiseVariablesAndroid();
return
}
},
onFailure: function (err) {
console.log(" callbackConvert onFailure")
console.error(err);
result.message = "Error converting file"
_this.rejectConvertMp4ToWav(result)
cleanPromiseVariablesAndroid();
return
}
})
var callbackConvert = new IConvertCallback();
var ILoadCallback = cafe.adriel.androidaudioconverter.callback.ILoadCallback.extend({
onSuccess: function () {
console.log("callbackLoad onSuccess");
var transcode = new cafe.adriel.androidaudioconverter.AndroidAudioConverter.with(context)
transcode.setFile(_this.file)
transcode.setFormat(cafe.adriel.androidaudioconverter.model.AudioFormat.WAV);
transcode.setCallback(callbackConvert)
transcode.convert();
},
onFailure: function (err) {
console.log("callbackLoad onFailure");
console.log(err)
result.message = "Error converting file"
_this.rejectConvertMp4ToWav(result)
cleanPromiseVariablesAndroid();
return
}
})
var callbackLoad = new ILoadCallback()
cafe.adriel.androidaudioconverter.AndroidAudioConverter.load(context, callbackLoad)
})
}
Для воспроизведения аудио я использую этот код:
playFromFile: function (path) {
console.log("playFromFile")
return new Promise(function (resolve, reject) {
var result = {
code: -1,
message: ""
}
var playerOptions = {
audioFile: path,
loop: false,
completeCallback: function () {
console.log("completeCallback");
},
errorCallback: function (errorObject) {
console.log("errorCallback");
console.log(JSON.stringify(errorObject));
},
infoCallback: function (args) {
console.log("infoCallback");
console.log(JSON.stringify(args));
}
};
player.playFromFile(playerOptions).then(function (res) {
console.log("result player.playFromFile")
result.code = 1
result.message = "Correct"
return resolve(result)
})
.catch(function (err) {
console.log("error playFromFile", err);
result.message = "An error ocurred playing file"
return reject(result)
});
})
}
Чтобы получить контекст:
getAndroidContext: function () {
var _this = this;
var ctx = app.android.context
if (!ctx) {
ctx = app.getNativeApplication().getApplicationContext();
}
if (ctx === null) {
setTimeout(function () {
_this.getAndroidContext();
}, 200);
return;
}
return ctx;
}
Поток, которым я следую, - это записать аудио, воспроизвести и преобразовать его. Он отлично работает один раз, ошибки появляются, когда я конвертирую аудио.