Сбой Android при использовании контекста с двумя разными плагинами с использованием Nativescript. Конвертировать m4a в wav - PullRequest
0 голосов
/ 08 января 2019

В настоящее время я использую два плагина в моем приложении 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;
}

Поток, которым я следую, - это записать аудио, воспроизвести и преобразовать его. Он отлично работает один раз, ошибки появляются, когда я конвертирую аудио.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...