Discussion:
MediaPlayer plays sound but screen is black
Brendan
2009-02-14 21:24:39 UTC
Permalink
I'm just trying to play a local video that is a resource with the
MediaPlayer class in the most simple way possible. I have confirmed
that the video works with players that I download from the
marketplace, so I'm assuming that's not the issue.

The problem is that I just get a black screen with no video. There is
audio from the file playing though, so I know that the file resource
is being accessed correctly, it's just not showing anything on the
screen in the emulator.

The one other note is that at any time whenever I try to access
getVideoWidth() or getVideoHeight() I get this (non-blocking) error:

ERROR/MediaPlayerService(24): getVideoSize returned -1

Any ideas as to what I could be doing wrong?



import android.app.Activity;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.media.MediaPlayer;

public class Example extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

SurfaceView sv = new SurfaceView(this);
setContentView(sv);

SurfaceHolder holder = sv.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

new MediaPlayer();
MediaPlayer mp = MediaPlayer.create(this, R.raw.video);
//holder.setFixedSize(mp.getVideoWidth(), mp.getVideoHeight
());
mp.setDisplay(holder);
mp.start();
}
}
Marco Nelissen
2009-02-14 21:32:57 UTC
Permalink
Several things potentially wrong with your code:
- you're using MediaPlayer.create(), which calls prepare() for you. IIRC,
setDisplay() needs to be called *before* prepare(), so you won't be able to
use any of the MediaPlayer.create convenience methods.
- the way you create and use the SurfaceView, you'll probably end up with a
0-sized Surface, so try specifying the SurfaceView in an xml layout and
using that.
- depending on the type of video, size information may not be available
until decoding has started. There's a callback/listener for that.
Post by Brendan
I'm just trying to play a local video that is a resource with the
MediaPlayer class in the most simple way possible. I have confirmed
that the video works with players that I download from the
marketplace, so I'm assuming that's not the issue.
The problem is that I just get a black screen with no video. There is
audio from the file playing though, so I know that the file resource
is being accessed correctly, it's just not showing anything on the
screen in the emulator.
The one other note is that at any time whenever I try to access
ERROR/MediaPlayerService(24): getVideoSize returned -1
Any ideas as to what I could be doing wrong?
import android.app.Activity;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.media.MediaPlayer;
public class Example extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SurfaceView sv = new SurfaceView(this);
setContentView(sv);
SurfaceHolder holder = sv.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
new MediaPlayer();
MediaPlayer mp = MediaPlayer.create(this, R.raw.video);
//holder.setFixedSize(mp.getVideoWidth(), mp.getVideoHeight
());
mp.setDisplay(holder);
mp.start();
}
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Marco Nelissen
2009-02-14 21:35:20 UTC
Permalink
Post by Marco Nelissen
- you're using MediaPlayer.create(), which calls prepare() for you. IIRC,
setDisplay() needs to be called *before* prepare(), so you won't be able to
use any of the MediaPlayer.create convenience methods.
Scratch that. There's actually a version of MediaPlayer.create() that allows
you to specify the SurfaceHolder. Use that one instead of the one you're
using currently.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Brendan
2009-02-14 23:01:34 UTC
Permalink
Wow that sounds really convenient. Since the signature of the
MediaPlayer.create() that takes a SurfaceHolder requires the second
argument to be a URI and not a resource id, I tried creating a URI for
the resource by doing this:

Uri uri = Uri.parse("android.resource://com.example.www/" +
R.raw.video);

And this may be a total noob question, but is that the right way to
create a URI for a resource?
Because then when I passed it in like this:

MediaPlayer mp = MediaPlayer.create(this, uri, holder);

The app immediately closes after flashing up a black screen, with
these the last lines that the log gets:

INFO/ActivityManager(49): Process com.example.www (pid 642) has died.
DEBUG/Zygote(23): Process 642 terminated by signal (11)
Post by Marco Nelissen
Post by Marco Nelissen
- you're using MediaPlayer.create(), which calls prepare() for you. IIRC,
setDisplay() needs to be called *before* prepare(), so you won't be able to
use any of the MediaPlayer.create convenience methods.
Scratch that. There's actually a version of MediaPlayer.create() that allows
you to specify the SurfaceHolder. Use that one instead of the one you're
using currently.
Marco Nelissen
2009-02-14 23:16:17 UTC
Permalink
Post by Brendan
Wow that sounds really convenient. Since the signature of the
MediaPlayer.create() that takes a SurfaceHolder requires the second
argument to be a URI and not a resource id, I tried creating a URI for
Oh, right, of course. My original comment stands then :)
You'll have to use "new MediaPlayer" instead of the MediaPlayer.create
convenience method.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Brendan
2009-02-15 00:28:53 UTC
Permalink
Thanks for all your help! I've been trying out your original idea, but
I still seem to be having issues.

I have moved the SurfaceView to main.xml, it looks like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
<SurfaceView android:id="@+id/surface_view"
android:layout_height="fill_parent"
android:layout_width="fill_parent"></SurfaceView>
</LinearLayout>

And now onCreate looks like this:

setContentView(R.layout.main);
SurfaceView sv = (SurfaceView) findViewById
(R.id.surface_view);

SurfaceHolder holder = sv.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

try {
MediaPlayer mp = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd
(R.raw.video);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getLength());
afd.close();
mp.setDisplay(holder);
mp.prepare();
mp.start();
} catch {...}

There are no errors ever thrown, but the process dies on mp.prepare()
without any warning or useful debug info. Is there potentially some
other way I should be setting the data source for a resource? Or
something else I'm forgetting to do that would make prepare
mysteriously kill the entire process?
Post by Marco Nelissen
Post by Brendan
Wow that sounds really convenient. Since the signature of the
MediaPlayer.create() that takes a SurfaceHolder requires the second
argument to be a URI and not a resource id, I tried creating a URI for
Oh, right, of course. My original comment stands then :)
You'll have to use "new MediaPlayer" instead of the MediaPlayer.create
convenience method.
Marco Nelissen
2009-02-15 00:38:41 UTC
Permalink
I think you have to use the SurfaceHolder callbacks to find out when the
surface has actually been created, and *then* call setDisplay/prepare/start
Post by Brendan
Thanks for all your help! I've been trying out your original idea, but
I still seem to be having issues.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_height="fill_parent"
android:layout_width="fill_parent"></SurfaceView>
</LinearLayout>
setContentView(R.layout.main);
SurfaceView sv = (SurfaceView) findViewById
(R.id.surface_view);
SurfaceHolder holder = sv.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
try {
MediaPlayer mp = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd
(R.raw.video);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getLength());
afd.close();
mp.setDisplay(holder);
mp.prepare();
mp.start();
} catch {...}
There are no errors ever thrown, but the process dies on mp.prepare()
without any warning or useful debug info. Is there potentially some
other way I should be setting the data source for a resource? Or
something else I'm forgetting to do that would make prepare
mysteriously kill the entire process?
Post by Marco Nelissen
Post by Brendan
Wow that sounds really convenient. Since the signature of the
MediaPlayer.create() that takes a SurfaceHolder requires the second
argument to be a URI and not a resource id, I tried creating a URI for
Oh, right, of course. My original comment stands then :)
You'll have to use "new MediaPlayer" instead of the MediaPlayer.create
convenience method.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Brendan
2009-02-15 05:48:07 UTC
Permalink
Wow, thank you for helping me through this. That was the little last
little bit I needed. I finally got the video playing successfully by
waiting until surfaceCreated to try calling prepare.

Though I have to admit that it feels like a lot of code to just to
play a video.

Thanks again, I hope this helps anyone else who was having similar
issues.
Post by Marco Nelissen
I think you have to use the SurfaceHolder callbacks to find out when the
surface has actually been created, and *then* call setDisplay/prepare/start
Post by Brendan
Thanks for all your help! I've been trying out your original idea, but
I still seem to be having issues.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
android:layout_height="fill_parent"
android:layout_width="fill_parent"></SurfaceView>
</LinearLayout>
      setContentView(R.layout.main);
      SurfaceView sv = (SurfaceView) findViewById
(R.id.surface_view);
      SurfaceHolder holder = sv.getHolder();
      holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
       try {
          MediaPlayer mp = new MediaPlayer();
          AssetFileDescriptor afd = getResources().openRawResourceFd
(R.raw.video);
          mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getLength());
          afd.close();
          mp.setDisplay(holder);
          mp.prepare();
          mp.start();
       } catch {...}
There are no errors ever thrown, but the process dies on mp.prepare()
without any warning or useful debug info. Is there potentially some
other way I should be setting the data source for a resource? Or
something else I'm forgetting to do that would make prepare
mysteriously kill the entire process?
Post by Marco Nelissen
Post by Brendan
Wow that sounds really convenient. Since the signature of the
MediaPlayer.create() that takes a SurfaceHolder requires the second
argument to be a URI and not a resource id, I tried creating a URI for
Oh, right, of course. My original comment stands then :)
You'll have to use "new MediaPlayer" instead of the MediaPlayer.create
convenience method.
Marco Nelissen
2009-02-15 17:59:16 UTC
Permalink
Post by Brendan
Wow, thank you for helping me through this. That was the little last
little bit I needed. I finally got the video playing successfully by
waiting until surfaceCreated to try calling prepare.
Though I have to admit that it feels like a lot of code to just to
play a video.
That's why you'd normally use VideoView, which does all this for you.
VideoView doesn't support playing from a resource though, so you have to
jump through some extra hoops for that case.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Loading...