调用setDataSource(FileDescriptor)方法时出现异常(失败:状态= 0x80000000)

时间:2011-01-25 15:10:37

标签: android video-streaming media-player file-descriptor

我正在开发一个视频流应用程序,并且在使用FileDescriptor调用set setDataSource时遇到困难。 我希望我的应用程序在下载时播放视频,所以一旦我得到最小字节数,我将这些字节移动到另一个文件,以便在原始文件中下载时可以在另一个文件中播放。

所以,我检查一下我是否可以像这样启动媒体播放器:

if (mediaPlayer == null) {
                    // Only create the MediaPlayer once we have the minimum
                    // buffered data
                    if (totalKbRead >= INTIAL_KB_BUFFER) {
                        try {
                            startMediaPlayer();
                        } catch (Exception e) {
                            Log.e(getClass().getName(),
                                    "Error copying buffered conent.", e);
                        }
                    }
                } else if (mediaPlayer.getDuration()
                        - mediaPlayer.getCurrentPosition() <= 1000) {
                    transferBufferToMediaPlayer();
                }
}

这是startMediaPlayer方法代码:

private void startMediaPlayer() {
        try {
            File bufferedFile = new File(context.getCacheDir(), "playingMedia"
                    + (counter++) + ".dat");

            // bufferedFile is the one that'll be played
            moveFile(downloadingMediaFile, bufferedFile);

            mediaPlayer = createMediaPlayer(bufferedFile);

            mediaPlayer.start();

            playButton.setEnabled(true);
        } catch (IOException e) {
            Log.e(getClass().getName(), "Error initializing the MediaPlayer.",
                    e);
            return;
}

我使用以下代码移动文件:

public void moveFile(File oldLocation, File newLocation) throws IOException {

        if (oldLocation.exists()) {
            BufferedInputStream reader = new BufferedInputStream(
                    new FileInputStream(oldLocation));
            BufferedOutputStream writer = new BufferedOutputStream(
                    new FileOutputStream(newLocation, false));
            try {
                byte[] buff = new byte[8192];
                int numChars;
                while ((numChars = reader.read(buff, 0, buff.length)) != -1) {
                    writer.write(buff, 0, numChars);
                }
            } catch (IOException ex) {
                throw new IOException("IOException when transferring "
                        + oldLocation.getPath() + " to "
                        + newLocation.getPath());
            } finally {
                try {
                    if (reader != null) {
                        writer.flush();
                        writer.close();
                        reader.close();
                    }
                } catch (IOException ex) {
                    Log.e(getClass().getName(),
                            "Error closing files when transferring "
                                    + oldLocation.getPath() + " to "
                                    + newLocation.getPath());
                }
            }
        } else {
            throw new IOException(
                    "Old location does not exist when transferring "
                            + oldLocation.getPath() + " to "
                            + newLocation.getPath());
        }
    }
}

我最终在这里创建了MediaPlayer对象:

private MediaPlayer createMediaPlayer(File mediaFile) throws IOException {

        if(mediaPlayer != null){
            mediaPlayer.release();
        }

        MediaPlayer mPlayer = new MediaPlayer();
        mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            public boolean onError(MediaPlayer mp, int what, int extra) {
                Log.e(getClass().getName(), "Error in MediaPlayer: (" + what
                        + ") with extra (" + extra + ")");
                return false;
            }
        });

        // It appears that for security/permission reasons, it is better to pass
        // a FileDescriptor rather than a direct path to the File.
        // Also I have seen errors such as "PVMFErrNotSupported" and
        // "Prepare failed.: status=0x1" if a file path String is passed to
        // setDataSource().
        FileInputStream fis = new FileInputStream(mediaFile);

        mPlayer.reset();
        FileDescriptor fd = fis.getFD();
        mPlayer.setDataSource(fd);       // IM GETTING THE EXCEPTION HERE
        mPlayer.setDisplay(mHolder);
        mPlayer.prepare();
        return mPlayer;
    }

这是我得到的例外情况:

01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): Error initializing the MediaPlayer.
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229): java.io.IOException: setDataSourceFD failed.: status=0x80000000
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at android.media.MediaPlayer.setDataSource(Native Method)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:854)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at org.pfc.utils.StreamingMediaPlayer.createMediaPlayer(StreamingMediaPlayer.java:266)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at org.pfc.utils.StreamingMediaPlayer.startMediaPlayer(StreamingMediaPlayer.java:226)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at org.pfc.utils.StreamingMediaPlayer.access$4(StreamingMediaPlayer.java:203)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at org.pfc.utils.StreamingMediaPlayer$2.run(StreamingMediaPlayer.java:183)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at android.os.Handler.handleCallback(Handler.java:587)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at android.os.Looper.loop(Looper.java:144)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at android.app.ActivityThread.main(ActivityThread.java:4937)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at java.lang.reflect.Method.invokeNative(Native Method)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at java.lang.reflect.Method.invoke(Method.java:521)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-25 16:03:15.663: ERROR/org.pfc.utils.StreamingMediaPlayer(2229):     at dalvik.system.NativeStart.main(Native Method)

我整个上午都被困在这里,我真的找不到有关该错误的信息。有些人告诉我使用文件路径,但我得到了我在评论中谈到的另一个例外(正好在FileInputStream创建中)。

我真的迷失在这里,任何帮助都会非常感激

10 个答案:

答案 0 :(得分:38)

不要忘记许可

<uses-permission android:name="android.permission.INTERNET" /> 

答案 1 :(得分:22)

好的,我得出的结论是错误:

  

准备失败:status = 0x1(调用prepare()时)

  

setDataSourceFD失败:状态= 0x80000000(调用setDataSourceFD()时)

与文件格式有关,可能意味着该文件不完整,已损坏或类似...

当我在this链接中发帖时,我发现了一个特定的视频在流式传输时工作正常(虽然我使用setDataSource,而不是setDataSourceFD),但它会不适用于大多数视频。

答案 2 :(得分:1)

根据我的阅读,某些视频文件格式在文件的END上有“标题”信息。因此,您的FD必须是支持搜索功能才能从文件末尾获取“标题”。我怀疑你的媒体播放器输入文件在寻找文件的“结尾”时失败了。

我们正在研究相同的问题你有进一步的发展吗?

肖恩

答案 3 :(得分:1)

有相同的错误,并且已经阅读了上面的文件格式的答案,我放弃尝试使用我的.mov文件setDataSource,而是用我的Android Telefon Camera创建了一个视频,它给了我一个.mp4文件。 我把它放在图片/目录中。 这工作 - 我没有错误地setDataSource。 我希望这对某人有用。

File mediaStorageDir = new         File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES),     "MyDirectoryUnderPictures");
File mediaFile_mp4_android;
mediaFile_mp4_android = new File(mediaStorageDir.getPath()
                    + File.separator
                    + "mp4_test"
                    + ".mp4"); //video taken with android camera
String filePath_mp4_android = String.valueOf(mediaFile_mp4_android);
File file_mp4_android = new File(filePath_mp4_android);
Uri contentUri = Uri.fromFile(file_mp4_android);
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(String.valueOf(contentUri));

答案 4 :(得分:1)

我也有这个问题。当我按库从SDCard选择音频时,它可以工作,并且如果我按Stop并再次开始,也可以。但是当重新启动应用程序时,我没有打开库就玩,只保存了URL,它停止工作,并返回该错误:'java.io.IOException:setDataSource failed .: status = 0x80000000'

全局变量:

MediaPlayer media = new MediaPlayer();
TextView idenss;
static private int PICKFILE_RESULT_CODE = 1;
Boolean selectusicFromBworser = false;
Button playGlobal;

我的代码对话框:

private void viewDialogSounds(final Button sountlabel){
    final View dialogView = View.inflate(this, R.layout.dialoge_selectsouns, null);
    final androidx.appcompat.app.AlertDialog alertDialog = new androidx.appcompat.app.AlertDialog.Builder(this).create();

    alertDialog.setTitle(context.getString(R.string.sound));

    Button exitW, play, pause, sound_set;
    ListView listsounds;
    SoundSteucture strAdapHistory = new SoundSteucture();
    ArrayList<SoundSteucture> structureHistoryArr;
    SoundAdapter _adapterHistory = null;

    final TextView fileSelectedName;

    exitW = (Button) dialogView.findViewById(R.id.exitW);
    play = (Button) dialogView.findViewById(R.id.play);
    pause = (Button) dialogView.findViewById(R.id.pause);
    sound_set = (Button) dialogView.findViewById(R.id.sound_set);
    listsounds = (ListView) dialogView.findViewById(R.id.listsounds);
    fileSelectedName = (TextView) dialogView.findViewById(R.id.fileSelectedName);
    idenss = fileSelectedName;
    playGlobal = play;

    structureHistoryArr = new ArrayList<SoundSteucture>();

    fileSelectedName.setText(sountlabel.getText().toString());

    String [] LabelNames={"A desayunar","A la valenciana","Al currele","Apagas o apagas","Arroz 3 delicias","Clásico e infalible","Con café mejor",
                        "De buen humor","El coche fantástico","El gallo Claudio","Energía positiva","Final destroyer","Fresas con nata","Manos arriba","Profundidad",
                        "Sabanas pegadas","Sax o Phone","Tocando el cielo"};//indices

    final String [] fileNames={"a_desayunar","a_la_valenciana","al_currele","apagas_o_apagas","arroz_3_delicias","clasico_e_infalible","con_cafe_mejor",
                        "de_buen_humor","el_coche_fantastico","el_gallo_claudio","energia_positiva","final_destroyer","fresas_con_nata","manos_arriba","profundidad",
                        "sabanas_pegadas","sax_o_phone","tocando_el_cielo"};//archivos

    if (_adapterHistory != null) {
        _adapterHistory.clear(); //clear se usa solo con los arrayadapter, si fuera simple adapter llevaria removeAllViews
        _adapterHistory.notifyDataSetChanged();
    }
    for (int i=0;i<LabelNames.length;i++){
        strAdapHistory.setNames(LabelNames[i]);
        strAdapHistory.setIdentif(fileNames[i]);
        if(fileSelectedName.getText().toString().equals(fileNames[i].replace("_"," ")))
            strAdapHistory.setCheck("1"); //consultador
        else
            strAdapHistory.setCheck("0");

        structureHistoryArr.add(strAdapHistory);
        strAdapHistory = new SoundSteucture();
    }

    if (structureHistoryArr != null) {
        _adapterHistory = new SoundAdapter(this, structureHistoryArr,pause, play, fileSelectedName, listsounds, PICKFILE_RESULT_CODE);
        listsounds.setAdapter(_adapterHistory);
        _adapterHistory.notifyDataSetChanged();
    }

    pause.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            selectusicFromBworser = false;
            try {
                if (media != null) {
                    media.stop(); //error
                    media = null;
                    media = new MediaPlayer();
                }
            } catch(Exception e){
                Log.d("Nitif Activity", e.toString());
            }
        }
    });

    final Button pauseFinal = pause;
    play.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(!fileSelectedName.getText().toString().equals(getString(R.string.sound))) {
                pauseFinal.callOnClick();

                int resID = 0;
                if (!fileSelectedName.getText().toString().contains("/")) {
                    String tono = fileSelectedName.getText().toString().replace(" ","_");
                    resID = getResources().getIdentifier(tono, "raw", getPackageName());
                    media = MediaPlayer.create(view.getContext(), resID);
                    media.setVolume(1000, 1000);
                    media.start();
                } else {
                    try {
                        if (!selectusicFromBworser) {
                            media.setDataSource(context, Uri.parse(fileSelectedName.getText().toString()));
                        }
                        media.prepareAsync();
                        media.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                            @Override
                            public void onPrepared(MediaPlayer mediaPlayer) {
                                mediaPlayer.start();
                            }
                        });
                    } catch (Exception e) {
                        e.printStackTrace();
                        Log.e("eeee???", e.toString());
                    }
                }
            }
        }
    });

    exitW.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            pauseFinal.callOnClick();
            alertDialog.dismiss();
            selectusicFromBworser = false;
        }
    });
    sound_set.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            selectusicFromBworser = false;
            if((!fileSelectedName.getText().toString().equals(""))&&(!fileSelectedName.getText().toString().equals("fileB")))
                sountlabel.setText(fileSelectedName.getText().toString().replace("_"," "));
            pauseFinal.callOnClick();
            alertDialog.dismiss();
        }
    });

    alertDialog.setView(dialogView);
    alertDialog.show();
}

我的代码ArrayAdapter:

public class SoundAdapter extends ArrayAdapter<SoundSteucture> {
List<SoundSteucture> imageAndTexts1 =null;
Activity activity;
Button pause,play;
TextView fileSelectedName;
ListView listItems;
int PICKFILE_RESULT_CODE;


public SoundAdapter(Activity activity, List<SoundSteucture> imageAndTexts, Button pause, Button play, TextView fileSelectedName, ListView listItems, int PICKFILE_RESULT_CODE) {
    super(activity, 0, imageAndTexts);
    imageAndTexts1 = imageAndTexts;
    this.pause = pause;
    this.play = play;
    this.fileSelectedName = fileSelectedName;
    this.listItems = listItems;
    this.PICKFILE_RESULT_CODE = PICKFILE_RESULT_CODE;
}

static class ViewHolder {
    TextView labelFile;
    TextView fileName;
    ImageView deint;
}

public View getView(final int position, View rowView, ViewGroup parent) {
    activity = (Activity) getContext();

    ViewHolder holder = new ViewHolder();

    if (rowView == null) {
        LayoutInflater inflater = activity.getLayoutInflater();
        rowView = inflater.inflate(R.layout.adapter_sounds, parent, false);

        holder.labelFile = (TextView)rowView.findViewById(R.id.labelFile);
        holder.fileName = (TextView)rowView.findViewById(R.id.fileName);
        holder.deint = (ImageView) rowView.findViewById(R.id.deint);

        rowView.setTag(holder);
    }else {
        holder = (ViewHolder) rowView.getTag();
    }

    final String labelf = imageAndTexts1.get(position).getNames();
    final String labelN = imageAndTexts1.get(position).getIdentif();
    final String check = imageAndTexts1.get(position).getCheck();

    holder.labelFile.setText(labelf);
    holder.fileName.setText(labelN);
    if(check.equals("1")){
        holder.deint.setVisibility(View.VISIBLE);
    }else{
        holder.deint.setVisibility(View.GONE);
    }

    final ViewHolder finalHolder = holder;
    holder.labelFile.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            ImageView imageList;
            for(int a=0; a < listItems.getCount(); a++){
                try {
                    imageList = (ImageView) listItems.getChildAt(a).findViewById(R.id.deint);
                    imageList.setVisibility(View.GONE);
                }
                catch(Exception e1){ //if not checkBox, null View, etc

                }
            }
            for(int j=0; j < imageAndTexts1.size(); j++){
                imageAndTexts1.get(j).setCheck("0");
            }

            if(check.equals("0")){
                finalHolder.deint.setVisibility(View.VISIBLE);
                imageAndTexts1.get(position).setCheck("1");
            }else{
                finalHolder.deint.setVisibility(View.GONE);
                imageAndTexts1.get(position).setCheck("0");
            }
            fileSelectedName.setText(labelN.replace("_"," "));
            if(!finalHolder.labelFile.getText().equals("fileB"))
                play.callOnClick();
            else
                openfilesFolder();
        }
    });

    return rowView;
}

//files browser
private void openfilesFolder(){
    Intent chooseFile;
    Intent intent;
    chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
    chooseFile.setType("audio/*");
    //chooseFile.setType("*/*");
    intent = Intent.createChooser(chooseFile, activity.getString(R.string.choosefile));
    activity.startActivityForResult(intent, PICKFILE_RESULT_CODE);
}

主要活动中的活动结果:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == PICKFILE_RESULT_CODE && resultCode == Activity.RESULT_OK) {
        Uri content_describer = data.getData();
        Log.e("eeee???", "ee->" + data.getData().getPath());

        idenss.setText(content_describer.toString());
        selectusicFromBworser = true;

        try {
            media.setDataSource(this, content_describer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        playGlobal.callOnClick();
    }
}

答案 5 :(得分:0)

在我的情况下,从wav文件切换到mp3解决了状态= 0x80000000

的此异常

答案 6 :(得分:0)

在我的情况下,问题是因为当设备作为外部存储器安装到PC时繁忙的SD卡,因此检查文件是否可用解决了问题。也许它有助于某人

答案 7 :(得分:0)

如果您定位的是Marshmallow或更高版本,请确保您已正确请求Manifest.permission.WRITE_EXTERNAL_STORAGE权限。我尝试了许多不同的解决方案,包括另一个可以替代MediaMetadataRetriever的库,但事实证明我的一个代码路径没有请求适当的权限。

答案 8 :(得分:0)

从obb扩展文件加载视频时,我遇到了同样的问题。 我通过替换来修复它:

mPlayer.setDataSource(fd); 

使用:

mPlayer.setDataSource(fis.getFileDescriptor(),fis.getStartOffset(),fis.getLength());

答案 9 :(得分:0)

我同意Pedriyoo,我尝试使用以下视频格式和其他视频格式重现异常:AVI,MPG / MPEG,MOV,mov,mp4,m4v,flv,WMV,我注意到AVI,MPG / MPEG,并且WMV每次都为我抛出一个例外。最好在运行方法之前排除它们,并用try-catch对其进行包装。