Android MediaPlayer 无法 SetDataSource()

Posted

技术标签:

【中文标题】Android MediaPlayer 无法 SetDataSource()【英文标题】:Android MediaPlayer can't SetDataSource() 【发布时间】:2014-02-05 18:13:58 【问题描述】:

我正在尝试为媒体播放器设置数据源,但它一直抛出此异常。

java.io.IOException: setDataSourceFD 失败

我哪里错了?

java.io.IOException: setDataSourceFD failed.: status=0x80000000
    at android.media.MediaPlayer._setDataSource(Native Method)
    at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1025)
02-05 11:11:37.664 I/mono-stdout(19741):   at Android.Runtime.JNIEnv.CallVoidMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00063] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.2-branch/4b53fbd0/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:507 
    at futurestate.audiobook.droid.ui.views.home.HomeView.n_onCreate(Native Method)
    at futurestate.audiobook.droid.ui.views.home.HomeView.onCreate(HomeView.java:31)
    at android.app.Activity.performCreate(Activity.java:5231)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
    at android.app.ActivityThread.access$800(ActivityThread.java:135)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5017)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
    at

这是我的代码。 Player.SetDataSource() 是失败的行。

if (Player == null)

    try
    
        var expansionFile = ApkExpansionSupport.GetApkExpansionZipFile(Application.Context, 1, 0);
        var entry = expansionFile.GetEntry(FileName);

        // I can see all entries with the line below. 
        // Therefore the above code can reach into the obb and see the contents.
        // var entries = expansionFile.GetAllEntries();

        var pfd = ParcelFileDescriptor.Open(new File(entry.ZipFileName), ParcelFileMode.ReadOnly);
        var afd = new AssetFileDescriptor(pfd, entry.FileOffset, entry.FileSize);
        var fd = afd.FileDescriptor;

        Player = new MediaPlayer();
        Player.Reset();
        Player.SetWakeMode(Application.Context, WakeLockFlags.Partial);
        Player.Looping = false;

        Player.SetDataSource(fd, afd.StartOffset, afd.Length);
        Player.Prepare();
    
    catch (Exception ex)
    
        Console.Out.WriteLine(ex.Message);
        Console.Out.WriteLine(ex.Source);
        Console.Out.WriteLine(ex.InnerException);
        Console.Out.WriteLine(ex.StackTrace);
    

    SeekTo(_startingPointMsec);
    DurationMsec = (Player.Duration);

【问题讨论】:

【参考方案1】:

好吧,我想我不知道我应该感到愚蠢还是完全生气。我的方法的整个问题是由于微软的“NoCompression”想法有点歪斜。

注意:问题中的代码有效且正确”

问题在于我使用 Powershell 自动创建 .obb 文件。该脚本利用了System.IO.Compression,当我将System.IO.Compression.CompressionLevel 设置为NoCompression 时,它仍然损坏了我的obb 文件。

我启动了我的控制台并安装了 7zip(ps:chocolateyrocks.

> cinst 7zip

并使用Store模式重新创建了obb文件,一切正常。

现在已经解决了,这是我们的 PowerShell 构建脚本

function Invoke-CreateExpansionApk

    param(
        [Parameter(Position=0, HelpMessage="Type of apk to create: main|patch")]
        [ValidateSet('main','patch')]
        [System.String]$Type = 'main',
        [Parameter(Position=1, Mandatory=$true, HelpMessage="Must be the same name as your Play Store App")]
        [System.String]$ApkName,

        [Parameter(Position=2, Mandatory=$true)]
        [System.String]$SourceDir,
        [Parameter(Position=3, Mandatory=$true)]
        [System.String]$OutputDir,
        [Parameter(Position=4)]
        [System.Double]$Version = 1
    )
    $PRIVATE:bundleVersion = $Version

    $PRIVATE:fileName = "$OutputDir\$Type.$bundleVersion.$ApkName.obb"

    $pwd = Get-ModuleDirectory
    set-alias sz $pwd\7za.exe
    sz a -tzip $fileName $SourceDir -mx0

【讨论】:

以上是关于Android MediaPlayer 无法 SetDataSource()的主要内容,如果未能解决你的问题,请参考以下文章

Android MediaPlayer 无法 SetDataSource()

Android MediaPlayer 无法设置数据源 uri

无法在 android 中使用 MediaPlayer 播放 MediaStore.Audio 歌曲

无法使用 MediaPlayer 对象在 Android 中播放许多音频文件

Android:'无法播放此视频'; MediaPlayer和VideoView错误1 -38

无法使用 STREAM_VOICE_CALL 在 android java 中通过 MediaPlayer 播放音频