2016-07-30 100 views
3

由於JavaFx Media尚未移植到移動平臺,任何人都可以幫助我使用本機iOS APi播放聲音mp3文件,該文件將存儲在我的主資源文件夾中膠子項目。Gluon Mobile iOS音頻播放器

回答

3

在Android上,我們可以輕鬆地將本地API添加到Gluon項目的Android文件夾中(在Android上檢查此solution以使用本機媒體),在iOS文件夾上使用Media API的本機代碼(Objetive-C)是不夠的,因爲它必須被編譯,並且編譯的文件必須被包括到ipa中。

目前,Charm Down正在爲一堆服務做到這一點。如果您查看iOSbuild.gradle腳本,它包含xcodebuild任務,用於編譯和構建本地庫libCharm.a,後者應該包含在使用任何這些服務的任何iOS項目中。

我的建議將被克隆的魅力下,並提供新的服務:AudioService,與像一些基本的方法:

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

這項服務將被添加到Platform類:

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

你應該爲桌面(空),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 

and imp lementation 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的模塊,並添加音頻服務爲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"] 

建設項目

保存該項目,並從魅力下項目的根,在命令行中運行:

./gradlew clean build 

如果一切正常,你應該有:

  • 通用/建設/庫/ charm- down-common-2.1.0-SNAPSHOT.jar
  • Desktop/build/libs/charm-down-desktop-2.1.0-SNAPSHOT.jar
  • Android/build/libs/charm-down-android-2.1。 0-SNAPSHOT.jar
  • IOS/build/libs/charm-down-ios-2.1.0-S NAPSHOT.jar
  • IOS /編譯/本地/ libCharm.a

膠子工程

與那些依賴和本地庫,您將能夠創建一個新的膠子工程,並添加罐子作爲本地依賴項(到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' 
} 

在您的瀏覽,檢索服務,並提供一些基本的UI來調用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'類未實現methodSignatureForSelector: - 提前出現故障 2016-07-30 12:32:50.770 GluonApp [3146:1115803] *** NSForwarding:警告:類Audio的對象0x1d34b64未實現doesNotRecognizeSelector: - 中止 –

+0

確保你已經按照每一步,有很多文件要修改。你有沒有設法成功修改你的修飾魅力?你在使用iOS sdk 9.3嗎? –

+0

我已經編輯了我的答案,但在'Audio.m'中稍作修改,刪除導入和不必要的'view'。 –