- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
与 my recent question on MediaRecorder
and createPipe()
相关,并在 this other SO question 中讨论了 createPipe()
技术,我现在正试图让 MediaPlayer
通过 ParcelFileDescriptor
和 createPipe()
处理由 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
正在正确构建。
PipeProvider
与 this sample project 中的相同,它适用于向 Adobe 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/
我使用 eclipse-indigo 和 android 2.3.3_r1,我从网络中的服务器下载了一个字符串。它是 docx 文件的内容。 我可以从它接收一个 ParcelFileDescritor
我正在尝试弄清楚如何在 ContentProvider.openFile 中传递数据流。要发送的数据是在 JNI 中创建的。我尝试使用传输线程创建管道,但由于管道损坏而遇到了很多麻烦。所以我想我可以将
我从下面的链接中了解了 ParcelFileDescriptor。 http://developer.android.com/reference/android/os/ParcelFileDescri
我有一个使用 ContentProvider 类的应用程序。在 openFile 方法中,我需要能够解码文件并作为数据流返回。所以我决定使用内置管道。 问题是如果我使用 createPipe 方法,我
我正在为这段安静的漫长岁月而苦苦挣扎,我决定需要帮助。此处描述了基本想法:Link 我想在录制时通过套接字将 MediaRecorder 的输出直接流式传输到我的服务器。 (在这种特定情况下,我想看看
我成功地通过 Mediarecorder 将视频录制到 SD 卡上但我想将此视频发送到服务器而不写入 SD 卡。我搜索了一下,发现 parcelFileDescriptor 是发送方式视频到 TCP
我正在两部安卓手机之间创建一个实时视频流的安卓应用程序。我已经在这些设备之间建立了套接字连接。我正在一个设备中捕获视频并将流发送到其他设备,但目前我只想保存在接收方移动设备中并保存它。我正在使用 Me
我正在尝试制作一个使用 MediaRecorder 录制音频的示例,录制的数据通过 Android(>=4.0) 上的 UDP 套接字传递。 阅读文章: Broadcasting video with
与 my recent question on MediaRecorder and createPipe() 相关,并在 this other SO question 中讨论了 createPipe(
我正在尝试制作一个录制音频的示例,数据存储由应用程序处理,而不是 MediaRecorder。用例包括将录音存储在内部存储器上或加密录音。 原则上,这应该使用 createPipe() 在 Parce
我已经解决了在 NDK 上编码时遇到的问题,但我不确定该解决方案是否规范,或者是否有规范的方法可以做到这一点。首先描述一下我所做的事情: 我似乎无法使用 Java 的 File 或 FileDescr
我有从后置摄像头录制视频的服务: this.mMediaRecorder = new MediaRecorder(); this.mMediaRecorder.setCamera(mCamera);
我的应用正在创建一个使用 ACTION_GET_INTENT 寻找图像 mime 类型的 Intent。返回后,我将检查数据 Intent 、从 URI 的内容解析器获取游标、检查 uri.toStr
我为我的 InstrumentationTestCase 子类编写了一个通用的 shellCommand 函数。对 executeShellCommand 的调用有效(命令已执行),但我对返回的 Pa
我有一个要传递给 ContentProvider 的 openFile() 方法的 InputStream。我能否以某种方式直接传递我的 InputStream,以某种方式将其包装在 ParcelFi
我应该如何形成在第 3 方查看器中显示我的应用程序内容的正确方式?我需要在画廊(或任何其他图像查看器)中显示图像,在某些 pdf 阅读器中显示 pdf,.. 数据通过实现 openFile() 方法并
我想通过使用 ParcelFileDescriptor.createPipe() 将 InputStream 从一个 Android 服务“发送”到在不同进程中运行的另一个服务。 ,一个流到流的复制线
我是一名优秀的程序员,十分优秀!