Anyone Have MediaPlayer Working with ParcelFileDescriptor and createPipe()? <p>Related to <a href="http://stackoverflow.com/questions/12894976/anyone-have-mediarecorder-working-with-parcelfiledescriptor-and-createpipe">my recent question on <code>MediaRecorder</code> and <code>createPipe()</code></a>, and a discussion of the <code>createPipe()</code> technique in <a href="http://stackoverflow.com/questions/12863731/open-a-file-from-archive-without-temporary-extraction/12863890">this other SO question</a>, I am now trying to get <code>MediaPlayer</code> to work with content served by a <code>ContentProvider</code> via <code>ParcelFileDescriptor</code> and <code>createPipe()</code>.</p> <p><a href="https://github.com/commonsguy/cw-omnibus/tree/master/Media/AudioPlayStream">This sample project</a> has my work to date. It is based off of <a href="https://github.com/commonsguy/cw-omnibus/tree/master/Media/Audio">an earlier sample that plays an OGG clip stored as a raw resource</a>. Hence, I know that my clip is fine.</p> <p>I have changed my <code>MediaPlayer</code> setup to:</p> <pre><code> 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); } } </code></pre> <p>Through logging in <code>PipeProvider</code>, I see that my <code>Uri</code> is being properly constructed.</p> <p><code>PipeProvider</code> is the same one as in <a href="https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/Pipe">this sample project</a>, which works for serving PDFs to Adobe Reader, which limits how screwed up my code can be. :-)</p> <p>Specifically, <code>openFile()</code> creates a pipe from <code>ParcelFileDescriptor</code>:</p> <pre><code> @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]); } </code></pre> <p>where the background thread does a typical stream-to-stream copy:</p> <pre><code> 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)) &gt; 0) { out.write(buf, 0, len); } in.close(); out.close(); } catch (IOException e) { Log.e(getClass().getSimpleName(), "Exception transferring file", e); } } } </code></pre> <p>However, <code>MediaPlayer</code> chokes:</p> <pre><code>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 </code></pre> <p>Has anyone seen working code for using <code>createPipe()</code> to serve media to <code>MediaPlayer</code>?</p> <p>Thanks in advance!</p>