2016-07-30 5 views
3

Поскольку JavaFx Media еще не портирован на мобильные платформы, может ли кто-нибудь помочь мне с использованием родной iOS APi для воспроизведения звукового mp3-файла, который будет храниться в моей папке main/resources в моем глюонный проект.Gluon Mobile iOS Audio Player

ответ

3

В то время как на Android мы можем легко добавить собственный API в папки Android проекта Gluon (отметьте это solution для использования родного носителя на Android), использование собственного кода (Objetive-C) с Media API в папках iOS недостаточно, так как он должен быть скомпилирован, и скомпилированные файлы должны быть включены в ipa.

В настоящее время Charm Down делает это для кучи услуг. Если вы посмотрите на сценарий build.gradle для iOS, он включает задачу xcodebuild для компиляции и сборки собственной библиотеки libCharm.a, которая позже должна быть включена в любой проект iOS с использованием любой из этих служб.

Мое предложение будет клонировать Charm вниз, и обеспечивая новый сервис: AudioService, с некоторыми основными методами, как:

public interface AudioService { 
    void play(String audioName); 
    void pause(); 
    void resume(); 
    void stop(); 
} 

Эта услуга будет добавлена ​​в Platform класс:

public abstract class Platform { 
    ... 
    public abstract AudioService getAudioService(); 
} 

и вы должны обеспечить реализацию для Desktop (пустой), Android (например, один из here) и iOS.

реализация IOS - Java

Вы должны добавить это к IOSPlatform класса:

public class IOSPlatform extends Platform { 
    ... 
    @Override 
    public AudioService getAudioService() { 
     if (audioService == null) { 
      audioService = new IOSAudioService(); 
     } 
     return audioService; 
    } 
} 

и создать IOSAudioService класс:

public class IOSAudioService implements AudioService { 

    @Override 
    public void play(String audioName) { 
     CharmApplication.play(audioName); 
    } 

    @Override 
    public void pause() { 
     CharmApplication.pause(); 
    } 

    @Override 
    public void resume() { 
     CharmApplication.resume(); 
    } 

    @Override 
    public void stop() { 
     CharmApplication.stop(); 
    } 
} 

Наконец, вы будете иметь для добавления собственных вызовов в CharmApplication:

public class CharmApplication { 
    static { 
     System.loadLibrary("Charm"); 
     _initIDs(); 
    } 
    ... 
    public static native void play(String audioName); 
    public static native void pause(); 
    public static native void resume(); 
    public static native void stop(); 
} 

IOS реализация - Objective-C

Теперь на родной папке, на CharmApplication.m, добавьте реализацию этих вызовов:

#include "CharmApplication.h" 
... 
#include "Audio.h" 

// Audio 
Audio *_audio; 

JNIEXPORT void JNICALL Java_com_gluonhq_charm_down_ios_CharmApplication_play 
(JNIEnv *env, jclass jClass, jstring jTitle) 
{ 
    NSLog(@"Play audio"); 
    const jchar *charsTitle = (*env)->GetStringChars(env, jTitle, NULL); 
    NSString *name = [NSString stringWithCharacters:(UniChar *)charsTitle length:(*env)->GetStringLength(env, jTitle)]; 
    (*env)->ReleaseStringChars(env, jTitle, charsTitle); 

    _audio = [[Audio alloc] init]; 
    [_audio playAudio:name]; 
    return; 
} 

JNIEXPORT void JNICALL Java_com_gluonhq_charm_down_ios_CharmApplication_pause 
(JNIEnv *env, jclass jClass) 
{ 
    if (_audio) 
    { 
     [_audio pauseAudio]; 
    } 
    return; 
} 

JNIEXPORT void JNICALL Java_com_gluonhq_charm_down_ios_CharmApplication_resume 
(JNIEnv *env, jclass jClass) 
{ 
    if (_audio) 
    { 
     [_audio resumeAudio]; 
    } 
    return; 
} 

JNIEXPORT void JNICALL Java_com_gluonhq_charm_down_ios_CharmApplication_stop 
(JNIEnv *env, jclass jClass) 
{ 
    if (_audio) 
    { 
     [_audio stopAudio]; 
    } 
    return; 
} 

и создать файл заголовка Audio.h:

#import <AVFoundation/AVFoundation.h> 
#import <UIKit/UIKit.h> 

@interface Audio :UIViewController <AVAudioPlayerDelegate> 
{ 
} 
    - (void) playAudio: (NSString *) audioName; 
    - (void) pauseAudio; 
    - (void) resumeAudio; 
    - (void) stopAudio; 
@end 

и исполнение Audio.m.Это одна основана на этом tutorial:

#include "Audio.h" 
#include "CharmApplication.h" 

@implementation Audio 

AVAudioPlayer* player; 

- (void)playAudio:(NSString *) audioName 
{ 
    NSString* fileName = [audioName stringByDeletingPathExtension]; 
    NSString* extension = [audioName pathExtension]; 

    NSURL* url = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"%@",fileName] withExtension:[NSString stringWithFormat:@"%@",extension]]; 
    NSError* error = nil; 

    if(player) 
    { 
     [player stop]; 
     player = nil; 
    } 

    player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; 
    if(!player) 
    { 
     NSLog(@"Error creating player: %@", error); 
     return; 
    } 
    player.delegate = self; 
    [player prepareToPlay]; 
    [player play]; 

} 

- (void)pauseAudio 
{ 
    if(!player) 
    { 
     return; 
    } 
    [player pause]; 
} 

- (void)resumeAudio 
{ 
    if(!player) 
    { 
     return; 
    } 
    [player play]; 
} 

- (void)stopAudio 
{ 
    if(!player) 
    { 
     return; 
    } 
    [player stop]; 
    player = nil; 
} 

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag 
{ 
    NSLog(@"%s successfully=%@", __PRETTY_FUNCTION__, flag ? @"YES" : @"NO"); 
} 

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error 
{ 
    NSLog(@"%s error=%@", __PRETTY_FUNCTION__, error); 
} 

@end 

Построить родную библиотеку

Отредактируйте build.gradle для модуля IOS и добавить службу Audio к xcodebuild задачи:

def nativeSources = ["$project.projectDir/src/main/native/CharmApplication.m", 
        ..., 
        "$project.projectDir/src/main/native/Audio.m"] 

... 
def compileOutputs = [ 
       "$project.buildDir/native/$arch/CharmApplication.o", 
       "$project.buildDir/native/$arch/Charm.o", 
       ..., 
       "$project.buildDir/native/$arch/Audio.o"] 

Постройте проект

Сохранить проект, и от корня проекта Charm вниз, в командной строке запуска:

./gradlew clean build 

Если все в порядке, вы должны иметь:

  • Общие/строить/ЛИЭС/Шарм вниз общего 2.1.0-SNAPSHOT.jar
  • Desktop/сборки/ЛИЭС/шарм-вниз настольных 2.1.0-SNAPSHOT.jar
  • Android/сборки/ЛИЭС/шарм-вниз-андроид-2,1. 0-SNAPSHOT.jar
  • IOS/build/libs/charm-down-ios-2.1 0,0-SNAPSHOT.jar
  • IOS/сборки/нативный/libCharm.a

Gluon Проект

С этими зависимостями и родной библиотеки, вы сможете создать новый проект ГЛЮОНА , и добавьте банки как локальные зависимости (в папку libs).

Что касается родной библиотеки, ее следует добавить к этому пути: src/ios/jniLibs/libCharm.a.

Обновление build.gradle сценария:

repositories { 
    flatDir { 
     dirs 'libs' 
    } 
    jcenter() 
    ... 
} 

dependencies { 
    compile 'com.gluonhq:charm-glisten:3.0.0' 
    compile 'com.gluonhq:charm-down-common:2.1.0-SNAPSHOT' 
    compile 'com.gluonhq:charm-glisten-connect-view:3.0.0' 

    iosRuntime 'com.gluonhq:charm-glisten-ios:3.0.0' 
    iosRuntime 'com.gluonhq:charm-down-ios:2.1.0-SNAPSHOT' 
} 

На ваш взгляд, получить услугу и предоставить некоторые основные интерфейс для вызова play("audio.mp3"), pause(), resume() и stop() методы:

private boolean pause; 

public BasicView(String name) { 
    super(name); 

    AudioService audioService = PlatformFactory.getPlatform().getAudioService(); 
    final HBox hBox = new HBox(10, 
      MaterialDesignIcon.PLAY_ARROW.button(e -> audioService.play("audio.mp3")), 
      MaterialDesignIcon.PAUSE.button(e -> { 
       if (!pause) { 
        audioService.pause(); 
        pause = true; 
       } else { 
        audioService.resume(); 
        pause = false; 
       } 

      }), 
      MaterialDesignIcon.STOP.button(e -> audioService.stop())); 
    hBox.setAlignment(Pos.CENTER); 
    setCenter(new StackPane(hBox)); 
} 

Наконец, место аудиофайла, например audio.mp3, под src/ios/assets/audio.mp3, для создания и развертывания в iOS.

Надеюсь, этот API будет предоставлен Charm Down в ближайшее время. Также, если вы придумали хорошую реализацию, не стесняйтесь поделиться ею и создать Pull Request.

+0

После применения всех этих изменений приложение застыло. журнал имеет этот выход: 2016-07-30 12: 32: 50.769 GluonApp [3146: 1115803] Воспроизвести аудио 2016-07-30 12: 32: 50.770 GluonApp [3146: 1115803] *** NSForwarding: warning: object 0x1d34b64 класса «Audio» не реализует методSignatureForSelector: - проблема впереди 2016-07-30 12: 32: 50.770 GluonApp [3146: 1115803] *** NSForwarding: warning: объект 0x1d34b64 класса «Audio» не реализует doesNotRecognizeSelector: - abort –

+0

Убедитесь, что вы выполнили каждый шаг, есть много файлов для изменения. Удалось ли вам успешно создать модифицированный Charm Down? Вы используете iOS sdk 9.3? –

+0

Я отредактировал свой ответ, но с незначительными изменениями в 'Audio.m', удалением импорта и ненужным' view'. –