gpt4 book ai didi

android - 任何人都有 MediaPlayer 使用 ParcelFileDescriptor 和 createPipe()?

转载 作者:IT老高 更新时间:2023-10-28 23:23:20 28 4
gpt4 key购买 nike

my recent question on MediaRecorder and createPipe() 相关,并在 this other SO question 中讨论了 createPipe() 技术,我现在正试图让 MediaPlayer 通过 ParcelFileDescriptorcreatePipe() 处理由 ContentProvider 提供的内容.

This sample project有我迄今为止的工作。它基于 an earlier sample that plays an OGG clip stored as a raw resource .因此,我知道我的剪辑很好。

我已将 MediaPlayer 设置更改为:

  private void loadClip() {
try {
mp=new MediaPlayer();
mp.setDataSource(this,
PipeProvider.CONTENT_URI.buildUpon()
.appendPath("clip.ogg")
.build());
mp.setOnCompletionListener(this);
mp.prepare();
}
catch (Exception e) {
goBlooey(e);
}
}

通过登录 PipeProvider,我看到我的 Uri 正在正确构建。

PipeProviderthis sample project 中的相同,它适用于向 Adob​​e Reader 提供 PDF 文件,这限制了我的代码可能被搞砸的程度。 :-)

具体来说,openFile()ParcelFileDescriptor 创建一个管道:

  @Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
ParcelFileDescriptor[] pipe=null;

try {
pipe=ParcelFileDescriptor.createPipe();
AssetManager assets=getContext().getResources().getAssets();

new TransferTask(assets.open(uri.getLastPathSegment()),
new AutoCloseOutputStream(pipe[1])).start();
}
catch (IOException e) {
Log.e(getClass().getSimpleName(), "Exception opening pipe", e);
throw new FileNotFoundException("Could not open pipe for: "
+ uri.toString());
}

return(pipe[0]);
}

后台线程在哪里进行典型的流到流复制:

  static class TransferTask extends Thread {
InputStream in;
OutputStream out;

TransferTask(InputStream in, OutputStream out) {
this.in=in;
this.out=out;
}

@Override
public void run() {
byte[] buf=new byte[1024];
int len;

try {
while ((len=in.read(buf)) > 0) {
out.write(buf, 0, len);
}

in.close();
out.close();
}
catch (IOException e) {
Log.e(getClass().getSimpleName(),
"Exception transferring file", e);
}
}
}

但是,MediaPlayer 阻塞:

10-16 13:33:13.203: E/MediaPlayer(3060): Unable to to create media player
10-16 13:33:13.203: D/MediaPlayer(3060): Couldn't open file on client side, trying server side
10-16 13:33:13.207: E/TransferTask(3060): Exception transferring file
10-16 13:33:13.207: E/TransferTask(3060): java.io.IOException: write failed: EPIPE (Broken pipe)
10-16 13:33:13.207: E/TransferTask(3060): at libcore.io.IoBridge.write(IoBridge.java:462)
10-16 13:33:13.207: E/TransferTask(3060): at java.io.FileOutputStream.write(FileOutputStream.java:187)
10-16 13:33:13.207: E/TransferTask(3060): at com.commonsware.android.audiolstream.PipeProvider$TransferTask.run(PipeProvider.java:120)
10-16 13:33:13.207: E/TransferTask(3060): Caused by: libcore.io.ErrnoException: write failed: EPIPE (Broken pipe)
10-16 13:33:13.207: E/TransferTask(3060): at libcore.io.Posix.writeBytes(Native Method)
10-16 13:33:13.207: E/TransferTask(3060): at libcore.io.Posix.write(Posix.java:178)
10-16 13:33:13.207: E/TransferTask(3060): at libcore.io.BlockGuardOs.write(BlockGuardOs.java:191)
10-16 13:33:13.207: E/TransferTask(3060): at libcore.io.IoBridge.write(IoBridge.java:457)
10-16 13:33:13.207: E/TransferTask(3060): ... 2 more
10-16 13:33:13.211: E/MediaPlayer(3060): Unable to to create media player
10-16 13:33:13.218: E/TransferTask(3060): Exception transferring file
10-16 13:33:13.218: E/TransferTask(3060): java.io.IOException: write failed: EPIPE (Broken pipe)
10-16 13:33:13.218: E/TransferTask(3060): at libcore.io.IoBridge.write(IoBridge.java:462)
10-16 13:33:13.218: E/TransferTask(3060): at java.io.FileOutputStream.write(FileOutputStream.java:187)
10-16 13:33:13.218: E/TransferTask(3060): at com.commonsware.android.audiolstream.PipeProvider$TransferTask.run(PipeProvider.java:120)
10-16 13:33:13.218: E/TransferTask(3060): Caused by: libcore.io.ErrnoException: write failed: EPIPE (Broken pipe)
10-16 13:33:13.218: E/TransferTask(3060): at libcore.io.Posix.writeBytes(Native Method)
10-16 13:33:13.218: E/TransferTask(3060): at libcore.io.Posix.write(Posix.java:178)
10-16 13:33:13.218: E/TransferTask(3060): at libcore.io.BlockGuardOs.write(BlockGuardOs.java:191)
10-16 13:33:13.218: E/TransferTask(3060): at libcore.io.IoBridge.write(IoBridge.java:457)
10-16 13:33:13.218: E/TransferTask(3060): ... 2 more

有没有人见过使用 createPipe()MediaPlayer 提供媒体的工作代码?

提前致谢!

最佳答案

我不确定这是否可行。当我运行这段代码时,我看到了这个踪迹:

I/AudioSystem(30916): getting audio flinger
I/AudioSystem(30916): returning new audio session id
D/IAudioFlinger(30916): newAudioSessionId In
D/AudioFlinger(28138): nextUniqueId, current 178
D/IAudioFlinger(30916): newAudioSessionId Out, id = 178
D/MediaPlayer(30916): setDataSource(Context context, content://com.commonsware.android.audiolstream/clip.ogg, Map<String, String> headers) in
D/MediaPlayer(30916): setDataSource(FileDescriptor fd) in
E/MediaPlayerService(28138): offset error

“偏移错误”来自 AOSP 中 MediaPlayerService.cpp 中的以下行,它在管道的读取端执行 fstat():

status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
{
struct stat sb;
int ret = fstat(fd, &sb);

....

if (offset >= sb.st_size) {
LOGE("offset error");
::close(fd);
return UNKNOWN_ERROR;
}

并且 sb.st_size 报告为 -1(通过 Java 级别的 ParcelFileDescriptor 上的 getStatSize())。错误处理程序关闭描述符,因此不久之后出现了损坏的管道错误。

根据我的经验,MediaPlayer 有很多这样的故障。除了直接在本地文件上以及(非常错误地)用于 HTTP 流媒体之外,我从未见过它适用于任何东西。我最终移植了 FFmpeg 来解决它的众多缺陷。

关于android - 任何人都有 MediaPlayer 使用 ParcelFileDescriptor 和 createPipe()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12920429/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com