2011-03-25 138 views
1

我編寫了一個使用FFmpeg解碼aydio的腳本。下面的代碼:通過音頻軌道在Android中播放音樂


JNIEXPORT jint JNICALL Java_org_libsdl_app_SDLActivity_main(JNIEnv* env, jobject obj, int argc, jstring argv, jbyteArray array) { 
     AVFormatContext *pFormatCtx; 
     int    i, videoStream, audioStream; 
     AVCodecContext *pCodecCtx; 
     AVCodec   *pCodec; 
     AVFrame   *pFrame; 
     AVPacket  packet; 
     int    frameFinished; 
     float   aspect_ratio; 

     AVCodecContext *aCodecCtx; 
     AVCodec   *aCodec; 

     SDL_Overlay  *bmp; 
     SDL_Surface  *screen; 
     SDL_Rect  rect; 
     SDL_Event  event; 
     SDL_AudioSpec wanted_spec, spec; 
     AVCodecContext *c= NULL; 
     int out_size, len; 
     int16_t *audio_buf; 
     uint8_t *outbuf; 
     uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; 
     char *pAudioBuffer = (char *) av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE * 2); 






     av_register_all(); 

     char *str = (*env)->GetStringUTFChars(env, argv, 0); 


     if(av_open_input_file(&pFormatCtx, str, NULL, 0, NULL)!=0) 
     return -150; // Couldn't open file 


     if(av_find_stream_info(pFormatCtx)nb_streams; i++) { 
     if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO && 
      videoStream streams[i]->codec->codec_type==CODEC_TYPE_AUDIO && 
      audioStream streams[audioStream]->codec; 



     aCodec = avcodec_find_decoder(aCodecCtx->codec_id); 
     if(!aCodec) { 
     fprintf(stderr, "Unsupported codec!\n"); 
     return -45; 
     } 

     avcodec_open(aCodecCtx, aCodec); 
     c=avcodec_alloc_context(); 
     packet_queue_init(&audioq); 
     while (av_read_frame(pFormatCtx, &packet)>= 0) { 
      if (aCodecCtx->codec_type == AVMEDIA_TYPE_AUDIO) { 
         int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2; 
         int size=packet.size; 
         while(size > 0) { 
           int len = avcodec_decode_audio3(aCodecCtx, (int16_t *) pAudioBuffer, &data_size, &packet); 

           jbyte *bytes = (*env)->GetByteArrayElements(env, array, NULL); 
           memcpy(bytes, (int16_t *) pAudioBuffer, size); 
           (*env)->ReleaseByteArrayElements(env, array, bytes, 0); 


           size = packet.size-len; 
           } 
      } 

    } 


return 5; 
} 

這裏是程序的Java代碼:


package org.libsdl.app; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 
import javax.microedition.khronos.egl.*; 

import android.app.*; 
import android.content.*; 
import android.view.*; 
import android.os.*; 
import android.util.Log; 
import android.graphics.*; 
import android.text.method.*; 
import android.text.*; 
import android.media.*; 
import android.hardware.*; 
import android.content.*; 

import java.lang.*; 

public class SDLActivity extends Activity { 

    protected void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     AudioTrack track; 

     int bufSize = AudioTrack.getMinBufferSize(44100,        AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
         AudioFormat.ENCODING_PCM_16BIT); 


     track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
        AudioFormat.ENCODING_PCM_16BIT, bufSize, AudioTrack.MODE_STREAM); 

     track.play(); 

      byte[] bytes = new byte[bufSize]; 

      int res = main(2, "/sdcard/muzika_iz_reklami_bmw_5_series_-_bmw_5_series.mp3", bytes); 

      track.write(bytes, 0, bytes.length); 
      System.out.println(res); 





    } 
    native int main(int count, String file, byte[] array); 

    static { 

     System.loadLibrary("test"); 
    } 



/** 
    Simple nativeInit() runnable 
*/ 



} 

當我運行的音樂是不是在玩。我究竟做錯了什麼?

回答

3

每次將新的解碼數據複製到您的數組時,您應該連續調用track.write(bytes,0,bytes.length),而不僅僅是一次。

在Java代碼中

void playSound(byte[] buf, int size) { 
    track.write(buf, 0, size); 
} 

添加一個新的方法,然後調用它在你的C代碼:

jclass cls = (*env)->GetObjectClass(env, obj); 
jmethodID play = (*env)->GetMethodID(env, cls, "playsound", "([BI)V");//At the begining of your main function 

(*env)->CallVoidMethod(env, obj, play, array, size);//After (*env)->ReleaseByteArrayElements(env, array, bytes, 0); 

祝你好運!

+0

謝謝,但可以在我的代碼中展示如何解決它?如果不難... – Kyborg2011 2011-03-25 17:06:55

+0

我已經更新了答案〜 – Bolton 2011-03-28 02:41:32

+0

謝謝,但我有一個新問題。如果不是困難的話:http://stackoverflow.com/questions/5448990/ffmpeg-and-types-of-samples – Kyborg2011 2011-03-28 03:52:33