我正在开发一个视频流应用程序,并且在使用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创建中)。
我真的迷失在这里,任何帮助都会非常感激
答案 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对其进行包装。