ANE中如何調(diào)用lame庫在iOS平臺WAV轉換MP3
代碼中包含了三個功能俺榆,輸出sayHello,檢測耳機是否插入惭聂,MP3轉換
OC部分
//
// Main.m
// HelloLib
//
// Created by Darren on 16/3/9.
// Copyright ? 2016年 darren. All rights reserved.
//
#import "FlashRuntimeExtensions.h"
#import <AudioToolbox/AudioToolbox.h>
#import "lame.h"
void dispatchMsgEvent(NSString *msg,NSString *code);
void outLog(NSString *msg,NSString *code);
NSString * getStringFromFREObject(FREObject obj);
FREContext eventContext;
lame_t lame;
void outLog(NSString *msg,NSString *code)
{
dispatchMsgEvent(msg,code);
}
void dispatchMsgEvent(NSString *msg,NSString *code)
{
if (eventContext == NULL) {
return;
}
const uint8_t *eventCode = (const uint8_t *)[msg UTF8String];
const uint8_t *msgCode = (const uint8_t *)[code UTF8String];
FREDispatchStatusEventAsync(eventContext, eventCode, msgCode);
}
//將FREObject轉成NSString
NSString * getStringFromFREObject(FREObject obj)
{
uint32_t length;
const uint8_t *value;
FREGetObjectAsUTF8(obj, &length, &value);
return [NSString stringWithUTF8String:(const char *)value];
}
//
// wav轉換成mp3
//
FREObject wavToMP3(
FREContext ctx,
void* functionData,
uint32_t argc,
FREObject argv[]
)
{
FREObject obj;
outLog(@"log_event_out",@"進入wavToMP3");
NSString *pcmPath = getStringFromFREObject(argv[0]);
if (pcmPath == nil || [pcmPath isEqualToString:@""]) {
return NULL;
}
//獲取到document目錄
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *mp3Path = [docDir stringByAppendingString:@"/hehe.mp3"];
outLog(@"log_event_out",[NSString stringWithFormat:@"pcm => %@ mp3 => %@",docDir,mp3Path]);
int read,write;
FILE *pcm = fopen([pcmPath cStringUsingEncoding:1], "rb");
fseek(pcm, 4*1024, SEEK_CUR);
FILE *mp3 = fopen([mp3Path cStringUsingEncoding:1], "wb");
const int PCM_SIZE = 8192;
const int MP3_SIZE = 8192;
short int pcm_buffer[PCM_SIZE * 2];
unsigned char mp3_buffer[MP3_SIZE];
@try {
lame = lame_init();
//設置聲道
lame_set_num_channels(lame,2);
//設置采樣率
lame_set_in_samplerate(lame, 44100);
//壓縮比特率
lame_set_brate(lame, 128);
//模式 雙聲道蒲肋,單聲道,立體聲
lame_set_mode(lame, 1);
//品質(zhì) 0~9 (0最好 9最差)
lame_set_quality(lame, 5);
lame_init_params(lame);
do {
read = fread(pcm_buffer, 2 * sizeof(short int), PCM_SIZE, pcm);
if (read == 0) {
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
}else{
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
}
fwrite(mp3_buffer, write, 1, mp3);
} while (read != 0);
NSLog(@"轉換完成");
}
@catch (NSException *exception) {
outLog(@"log_event_out",[NSString stringWithFormat:@"error ==> %@",[exception debugDescription]]);
}
@finally {
//釋放資源
lame_close(lame);
fclose(pcm);
fclose(mp3);
}
uint8_t * reoutPath = (uint8_t *)[mp3Path UTF8String];
FRENewObjectFromUTF8(strlen((const char*)reoutPath), reoutPath, &obj);
return obj;
}
FREObject sayHello(
FREContext ctx,
void* functionData,
uint32_t argc,
FREObject argv[]
)
{
FREObject obj;
uint8_t * value = (uint8_t *)"Hello Adobe air";
FRENewObjectFromUTF8(strlen((const char*)value), value, &obj);
return obj;
}
/**
耳機檢測回調(diào)
*/
void audioRouteChangeListenerCallback(
void * inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void * inData
)
{
if (inID != kAudioSessionProperty_AudioRouteChange) {
return;
}
CFDictionaryRef routeChangeDic = (CFDictionaryRef)inData;
CFNumberRef routeChangeReasonRef = CFDictionaryGetValue(routeChangeDic, CFSTR(kAudioSession_AudioRouteChangeKey_Reason));
SInt32 routeChangeReason;
CFNumberGetValue(routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);
if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {
dispatchMsgEvent(@"AudioSessionRouteChangeReason_OldDeviceUnavailable",@"yes");
}else if(routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable){
dispatchMsgEvent(@"AudioSessionRouteChangeReason_NewDeviceAvailable",@"no");
}
}
/**
初始化耳機檢測
*/
FREObject initChectHeadset(
FREContext ctx,
void* functionData,
uint32_t argc,
FREObject argv[]
)
{
eventContext = ctx;
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionSetActive(YES);
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, nil);
return NULL;
}
void contextInit(
void* extData ,
const uint8_t* ctxType ,
FREContext ctx ,
uint32_t* numFunctionsToSet,
const FRENamedFunction** functionsToSet
)
{
*numFunctionsToSet = 3;
FRENamedFunction *functions = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)* *numFunctionsToSet);
functions[0].name = (const uint8_t*)"sayHello";
functions[0].functionData = NULL;
functions[0].function = &sayHello;
functions[1].name = (const uint8_t *)"initChectHeadset";
functions[1].functionData = NULL;
functions[1].function = &initChectHeadset;
functions[2].name = (const uint8_t *)"wavToMP3";
functions[2].functionData = NULL;
functions[2].function = &wavToMP3;
*functionsToSet = functions;
}
///
///初始化方法
///
void helloInitTest(
void** extDataToSet ,
FREContextInitializer* ctxInitializerToSet,
FREContextFinalizer* ctxFinalizerToSet
)
{
*ctxInitializerToSet = &contextInit;
}
as3代碼部分
package com.xd
{
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.StatusEvent;
import flash.external.ExtensionContext;
public class HelloANE extends EventDispatcher
{
private var ec:ExtensionContext = null;
public static const ID:String = "com.xd.hello";
public function HelloANE(target:IEventDispatcher=null)
{
super(target);
ec = ExtensionContext.createExtensionContext(ID,null);
if(ec){
ec.addEventListener(StatusEvent.STATUS,onStatus);
}
}
/**
* 初始化耳機檢測
*/
public function initChectHeadset():void
{
ec.call("initChectHeadset");
}
protected function onStatus(event:StatusEvent):void
{
trace("事件回調(diào) \n"+JSON.stringify(event));
}
public function sayHello():String
{
return ec.call("sayHello") as String;
}
/**
* 轉換MP3文件 巧颈,需要傳遞一個路徑過去
*
*/
public function wavToMP3(pcmPath:String):String{
return ec.call("wavToMP3",pcmPath) as String;
}
}
}
ANE開發(fā)步驟完整版 ANE for iOS