在 android 上播放本地 m3u8 文件,显示 setDataSourceFD 失败。:状态 = 0x80000000
Posted
技术标签:
【中文标题】在 android 上播放本地 m3u8 文件,显示 setDataSourceFD 失败。:状态 = 0x80000000【英文标题】:Play a local m3u8 file on android showing setDataSourceFD failed.: status=0x80000000 【发布时间】:2013-12-08 05:16:00 【问题描述】:我正在尝试使用 android mediaplayer 类播放存储在我的 sdcard 中的本地 m3u8 文件。m3u8 文件和 .ts 文件位于同一目录中。当我从中打开 m3u8 时,像 MXPlayer 这样的第三方播放器会加入 ts 文件并播放视频。但是使用android mediaplayer类会抛出以下错误`
无法创建媒体播放器 错误:setDataSourceFD 失败。:状态=0x80000000 java.io.IOException:setDataSourceFD 失败。:状态=0x80000000 在 android.media.MediaPlayer.setDataSource(本机方法) 在 android.media.MediaPlayer.setDataSource(MediaPlayer.java:1204) 在 com.tcs.hlsvideo.StreamingPlayer.playVideo(StreamingPlayer.java:87) 在 com.tcs.hlsvideo.StreamingPlayer.surfaceCreated(StreamingPlayer.java:148) 在 android.view.SurfaceView.updateWindow(SurfaceView.java:609) 在 android.view.SurfaceView.access$000(SurfaceView.java:86) 在 android.view.SurfaceView$3.onPreDraw(SurfaceView.java:178) 在 android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:707) 在 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1981) 在 android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1143) 在 android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4667) 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) 在 android.view.Choreographer.doCallbacks(Choreographer.java:555) 在 android.view.Choreographer.doFrame(Choreographer.java:525) 在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) 在 android.os.Handler.handleCallback(Handler.java:615) 在 android.os.Handler.dispatchMessage(Handler.java:92) 在 android.os.Looper.loop(Looper.java:137) 在 android.app.ActivityThread.main(ActivityThread.java:4960) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:511) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805) 在 dalvik.system.NativeStart.main(本机方法) setDataSourceFD 失败。:状态=0x80000000
我使用的代码是
private static final String TAG = StreamingPlayer.class.getSimpleName();
private String formatedIpAddress;
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder holder;
private String path;
//private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
mPreview = new SurfaceView(this);
holder = mPreview.getHolder();
holder.addCallback(this);
setContentView(mPreview);
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
formatedIpAddress = String.format("%d.%d.%d.%d", (ipAddress & 0xff),
(ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff));
Log.d(TAG, formatedIpAddress);
private void playVideo()
doCleanUp();
try
//local m3u8 file
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ts/prog_index.m3u8";
if (path == "")
// Tell the user to provide a media file URL.
Toast
.makeText(
this,
"Please edit MediaPlayerDemo_Video Activity,"
+ " and set the path variable to your media file URL.",
Toast.LENGTH_LONG).show();
Log.e("PATH", "Path = " + path);
// Create a new media player and set the listeners
mMediaPlayer = new MediaPlayer();
//mMediaPlayer.SET
mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepare();
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setAudiostreamType(AudioManager.STREAM_MUSIC);
catch (Exception e)
Log.e(TAG, "error: " + e.getMessage(), e);
Log.e(TAG, e.getMessage());
public void onBufferingUpdate(MediaPlayer arg0, int percent)
Log.d(TAG, "onBufferingUpdate percent:" + percent);
public void onCompletion(MediaPlayer arg0)
Log.d(TAG, "onCompletion called");
public void onVideoSizeChanged(MediaPlayer mp, int width, int height)
Log.v(TAG, "onVideoSizeChanged called");
if (width == 0 || height == 0)
Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
return;
//mIsVideoSizeKnown = true;
mVideoWidth = width;
mVideoHeight = height;
//&& mIsVideoSizeKnown
if (mIsVideoReadyToBePlayed )
startVideoPlayback();
public void onPrepared(MediaPlayer mediaplayer)
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
//&& mIsVideoSizeKnown
if (mIsVideoReadyToBePlayed )
startVideoPlayback();
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k)
Log.d(TAG, "surfaceChanged called");
public void surfaceDestroyed(SurfaceHolder surfaceholder)
Log.d(TAG, "surfaceDestroyed called");
public void surfaceCreated(SurfaceHolder holder)
Log.d(TAG, "surfaceCreated called");
playVideo();
@Override
protected void onPause()
super.onPause();
releaseMediaPlayer();
doCleanUp();
@Override
protected void onDestroy()
super.onDestroy();
releaseMediaPlayer();
doCleanUp();
private void releaseMediaPlayer()
if (mMediaPlayer != null)
mMediaPlayer.release();
mMediaPlayer = null;
private void doCleanUp()
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
//mIsVideoSizeKnown = false;
private void startVideoPlayback()
Log.v(TAG, "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start();
帮帮我,伙计们... `
【问题讨论】:
你找到解决方案了吗? 我也遇到了同样的问题,请问有什么有用的吗? 【参考方案1】:我不确定,但看起来 M3U8 文件不是媒体文件。它是一种播放列表文件格式。这意味着您必须解析它,从中获取媒体文件的路径并播放您获得的文件之一。
这里是格式的简短描述http://www.gravlab.com/2013/07/05/what-is-an-m3u8-file/。
要了解如何解析它,请查看以下答案:Parsing HLS m3u8 file using regular expressions
【讨论】:
以上是关于在 android 上播放本地 m3u8 文件,显示 setDataSourceFD 失败。:状态 = 0x80000000的主要内容,如果未能解决你的问题,请参考以下文章