android模拟器仅在播放视频时显示黑屏声音

时间:2011-10-30 07:03:40

标签: android android-emulator

android模拟器仅在播放视频时显示黑屏声音。我的代码如下。

我似乎在logcat中得到的错误是:

10-30 06:49:35.663: W/GraphicBufferAllocator(33): alloc(160, 128, 842094169, 00002930, ...) failed -22 (Invalid argument)
10-30 06:49:35.663: E/SurfaceFlinger(33): GraphicBufferAlloc::createGraphicBuffer(w=160, h=128) failed (Invalid argument), handle=0x0
10-30 06:49:35.663: E/SurfaceTexture(33): [SurfaceView] dequeueBuffer: SurfaceComposer::createGraphicBuffer failed
10-30 06:49:35.673: W/SoftwareRenderer(35): Surface::dequeueBuffer returned error -22

视频高度和宽度为

10-30 06:49:35.223: D/Video Height:(595): 128
10-30 06:49:35.223: D/Video Width:(595): 160

我在想也许安卓无法播放这么大的视频(它很小)但这看起来很荒谬。我已经尝试了几个视频,它不能播放任何一个(mp4或3gp)。我只听到声音。视频是黑色的。我可以在VLC中播放它们,因此视频文件很好。只是我无法在Android模拟器中使用这个媒体播放器应用程序播放它们。

我使用Android 4.0作为我的AVD。即PC上的模拟器。


package com.jevan.mediaplayer;

import java.io.IOException;
import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MediaPlayerActivity extends Activity 
    implements SurfaceHolder.Callback, OnPreparedListener,
    OnVideoSizeChangedListener {
/** Called when the activity is first created. */
private int mVideoWidth=0;
private int mVideoHeight=0;
private MediaPlayer mp = null;
private SurfaceHolder holder = null;
private SurfaceView sv = null;
private boolean mIsVideoReadyToBePlayed = false;
private boolean mIsVideoSizeKnown = false;
private Button myButton = null;

    public void surfaceCreated(SurfaceHolder holder) {
        /*MediaPlayer mediaPlayer = MediaPlayer.create(context, uri);
        mediaPlayer.start(); // no need to call prepare(); create() does that for you
        */
        Log.d("surfaceCreated()", "surfaceCreated called");
        mp = new MediaPlayer();

        AssetFileDescriptor afd = null;
        try {
            afd = getAssets().openFd("747.3gp");
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
        } catch (IllegalArgumentException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalStateException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            afd.close();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        /*
        try {
            mp.setDataSource("http://www.mp4point.com/downloads/d7c320246079.mp4");
        } catch (IllegalArgumentException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (SecurityException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalStateException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        */

        mp.setDisplay(holder);
        try {
            mp.prepare();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        mp.setOnPreparedListener(this);
        mp.setOnVideoSizeChangedListener(this);

        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);

        /*setVolumeControlStream(AudioManager.STREAM_MUSIC);*/

        mp.setScreenOnWhilePlaying(true); 

        Log.d("Video Height:", Integer.toString(mp.getVideoHeight()));
        Log.d("Video Width:", Integer.toString(mp.getVideoWidth()));

        mp.setLooping(false);

        //mp.start(); 
        // i.e. react on the end of the music-file: 
        /*
        mp.setOnCompletionListener(new 
                OnCompletionListener(){ 
            public void onCompletion(MediaPlayer arg0) { 
                // File has ended 
            } 
        });
        */

        Log.d("surfaceCreated()", "surfaceCreated finishing");
    }

    public void surfaceChanged(SurfaceHolder holder,
            int format, int width, int height) {
        // TODO Auto-generated method stub

    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub

    }

    public void onPrepared(MediaPlayer mediaplayer) {
        Log.d("onPrepared", "onPrepared called");
        mIsVideoReadyToBePlayed = true;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
            startVideoPlayback(mediaplayer);
        }
        Log.d("onPrepared", "onPrepared finishing");
    }

    private void startVideoPlayback(MediaPlayer mediaplayer) {
        if (!(mediaplayer.isPlaying())) {
            holder.setFixedSize(mVideoWidth, mVideoHeight);
            mediaplayer.start();
        }
    }

    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        Log.d("onVideoSizeChanged",
                "onVideoSizeChanged called (Width "+Integer.toString(width)+" Height "+Integer.toString(height)+")");
        if (width == 0 || height == 0) {
            Log.e("Log", "invalid video width(" + width + ") or height(" + height + ")");
            return;
        }
        mIsVideoSizeKnown = true;
        mVideoWidth = width;
        mVideoHeight = height;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
            startVideoPlayback(mp);
        }
    }

    private void releaseMediaPlayer() {
        Log.d("releaseMediaPlayer", "releaseMediaPlayer called");
        if (mp != null) {
            mp.release();
            mp = null;
            Log.d("releaseMediaPlayer", "mp release has been called and mp made null");
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaPlayer();
        doCleanUp();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseMediaPlayer();
        doCleanUp();
    }

    private void doCleanUp() {
        mVideoWidth = 0;
        mVideoHeight = 0;
        mIsVideoReadyToBePlayed = false;
        mIsVideoSizeKnown = false;
    }

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Log.d("onCreate", "onCreate called");
    sv = (SurfaceView) findViewById(R.id.surface_view); 
    holder = sv.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    myButton = (Button)this.findViewById(R.id.button); 
    myButton.setOnClickListener(new OnClickListener(){ 
           public void onClick(View arg0) {
               if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
                   startVideoPlayback(mp);
               }
           }
    });
    Log.d("onCreate", "onCreate finishing");
} 
}

我的main.xml看起来像这样:

 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent" android:layout_height="fill_parent">

<Button android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:id="@+id/button"
    android:text="Start Video" android:layout_alignParentBottom="true" />

<SurfaceView android:id="@+id/surface_view"
      android:layout_height="fill_parent"
      android:layout_width="fill_parent"
      android:layout_above="@+id/button"></SurfaceView>

 </RelativeLayout>

1 个答案:

答案 0 :(得分:1)

我对普通设备遇到了同样的问题,最糟糕的是它似乎每次都没有发生,因此调试起来非常困难。我建议使用VideoView,它会自动调整大小并保持相当一致,例如:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:layout_gravity="fill|bottom" android:gravity="fill|bottom">
    <LinearLayout android:layout_alignParentBottom="true"
        android:layout_alignParentTop="true" android:layout_alignParentRight="true"
        android:layout_alignParentLeft="true" android:layout_width="match_parent"
        android:layout_height="match_parent" android:gravity="center">
        <VideoView android:id="@+id/videoView"
            android:layout_centerInParent="true" android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
    <Button android:id="@+id/activate_button" style="@style/buttonStyle"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_gravity="bottom|center_horizontal"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true" android:layout_alignParentLeft="true"
        android:onClick="activateClick" android:text="@string/activateButtonLabel" />
</RelativeLayout>

用于:

public class ExternalMediaPreview extends Activity implements OnPreparedListener
    {

        private VideoView           mVideoView;
        protected int               resid;
        protected String            mediaPackage;
        protected ActivityInfo      mActivityInfo;

        public ExternalMediaPreview()
            {
                super();
            }

        @Override
        public void onCreate( Bundle icicle )
            {
                super.onCreate( icicle );
                requestWindowFeature( Window.FEATURE_NO_TITLE );
                setContentView( R.layout.video_preview );
                mVideoView = ( VideoView ) findViewById( R.id.videoView );
                mVideoView.setOnPreparedListener( this );
                try
                    {
                        Uri uri = Uri.parse( "android.resource://" + getPackageName() + "/" + R.raw.test_video );
                        mVideoView.setVideoURI( uri );
                        Log.i( TAG, "Uri loaded: " + uri.toString() );
                    }
                catch( Exception e )
                    {
                        e.printStackTrace();
                    }
            }
        @Override
        public void onPrepared( MediaPlayer mp )
            {
                Log.i( TAG, "videoView prepared, setting loop to true" );
                mp.setLooping( true );
                mVideoView.start();
            }
}