Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new API to FFmpegFrameGrabber/Recorder to take a stream as input parameter #95

Closed
rpgomes opened this issue Feb 19, 2015 · 13 comments

Comments

@rpgomes
Copy link

rpgomes commented Feb 19, 2015

This enhancement was open in:

https://code.google.com/p/javacv/issues/detail?id=363

Are you guys still planing to develop?

@saudet
Copy link
Member

saudet commented Feb 20, 2015

Of course, "planning" is a big word though. We only need to find someone to take on the workload! :) Are you willing to give it a try yourself?

@ardoramor
Copy link

I tried something in combining MediaCodec and JavaCV. I say something because I lack the full understanding of ffmpeg. You can find my SO question related to the attempt here: http://stackoverflow.com/questions/28775931/muxing-android-mediacodec-encoded-h264-packets-into-rtmp. If you can provide me with more clarification, I'd like to continue.

@saudet
Copy link
Member

saudet commented Mar 5, 2015

@ardoramor Could you explain how your SO question relates to this issue?

@ardoramor
Copy link

I was coming more from https://code.google.com/p/javacv/issues/detail?id=430&q=mediacodec but I think the purpose is the similar. At least one part of it deals with FFmpegFrameRecorder. For live streaming, integration of MediaCodec would simplify and enhance the streaming.

@saudet
Copy link
Member

saudet commented Mar 6, 2015

@ardoramor I see. It might be easier to try to get things running without MediaCodec or anything from Android, and just use FFmpeg and Java InputStream and OutputStream. And when that works, we can start looking into more complicated stuff from Android. What do you think?

saudet added a commit that referenced this issue Dec 27, 2016
…rder(OutputStream)` constructors (issue #95)

 * Make `FrameFilter`, `FrameGrabber`, and `FrameRecorder` implement `Closeable` to let us try-with-resources
@saudet
Copy link
Member

saudet commented Jan 15, 2017

Feature added in version 1.3.1. Enjoy!

@saudet saudet closed this as completed Jan 15, 2017
@beligum
Copy link

beligum commented Jan 16, 2017

Whow, this is great news, thanks!!

@pgfsim
Copy link

pgfsim commented Jan 16, 2017

Unfortunately I can't get OutputStream to work correctly. I'm converting images into video on android. Tried using 1.3 and 1.3.2 snapshot. The frames/bitmaps are valid as I checked them, but it will crash at recordImage(). The OutputStream/file also exists as i can easily write bytes to it myself.

  DocumentFile gjDir = mLocation.createFile("video/mp4", videotimeStamp + ".mp4");
   FileOutputStream out = null;
try{
       ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(gjDir.getUri(),"w");
       out = new FileOutputStream(pfd.getFileDescriptor());
       }catch(FileNotFoundException e){
       e.printStackTrace();
       }

       recorder=new FFmpegFrameRecorder(out,1920,1080,0);
       recorder.setVideoCodecName("libopenh264");
       recorder.setAudioChannels(0);
       recorder.setFormat("mp4");
       recorder.setPixelFormat(org.bytedeco.javacpp.avutil.AV_PIX_FMT_YUV420P);
       recorder.setFrameRate(10);

       recorder.start();
       Frame x=null;

       for(int d=0;d<totallistofimages;d++){
final ParcelFileDescriptor parcelFileDescriptor=getContentResolver().openFileDescriptor(listofImages.get(d).getUri(),"r");
final FileDescriptor fileDescriptor=parcelFileDescriptor.getFileDescriptor();
final Bitmap bitmap=BitmapFactory.decodeFileDescriptor(fileDescriptor);
       parcelFileDescriptor.close();
       AndroidFrameConverter androidFrameConverter=new AndroidFrameConverter();
       x=androidFrameConverter.convert(bitmap);

       recorder.record(x);
       }

       recorder.stop();
01-16 16:38:13.823 389-389/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
01-16 16:38:13.854 389-389/? A/DEBUG: backtrace:
01-16 16:38:13.854 389-389/? A/DEBUG:     #00 pc 0010d4e8  /data/app/com.s.time-1/lib/arm/libavformat.so
01-16 16:38:13.854 389-389/? A/DEBUG:     #01 pc 0010ef00  /data/app/com.s.time-1/lib/arm/libavformat.so (av_write_frame+336)
01-16 16:38:13.854 389-389/? A/DEBUG:     #02 pc 00cd12c5  /data/app/com.s.time-1/oat/arm/base.odex (offset 0x5ab000) (int org.bytedeco.javacpp.avformat.av_write_frame(org.bytedeco.javacpp.avformat$AVFormatContext, org.bytedeco.javacpp.avcodec$AVPacket)+112)
01-16 16:38:13.854 389-389/? A/DEBUG:     #03 pc 00bcea25  /data/app/com.s.time-1/oat/arm/base.odex (offset 0x5ab000) (void org.bytedeco.javacv.FFmpegFrameRecorder.writePacket(int, org.bytedeco.javacpp.avcodec$AVPacket)+960)
01-16 16:38:13.854 389-389/? A/DEBUG:     #04 pc 00bd0f09  /data/app/com.s.time-1/oat/arm/base.odex (offset 0x5ab000) (boolean org.bytedeco.javacv.FFmpegFrameRecorder.recordImage(int, int, int, int, int, int, java.nio.Buffer[])+5284)
01-16 16:38:13.854 389-389/? A/DEBUG:     #05 pc 00bcf195  /data/app/com.s.time-1/oat/arm/base.odex (offset 0x5ab000) (void org.bytedeco.javacv.FFmpegFrameRecorder.record(org.bytedeco.javacv.Frame, int)+448)
01-16 16:38:13.854 389-389/? A/DEBUG:     #06 pc 00bcefa3  /data/app/com.s.time-1/oat/arm/base.odex (offset 0x5ab000) (void org.bytedeco.javacv.FFmpegFrameRecorder.record(org.bytedeco.javacv.Frame)+62)
01-16 16:38:13.854 389-389/? A/DEBUG:     #07 pc 007e1d8f  /data/app/com.s.time-1/oat/arm/base.odex (offset 0x5ab000) (java.lang.String com.s.time.Rendering$Render.doInBackground(java.lang.String[])+8474)
01-16 16:38:13.854 389-389/? A/DEBUG:     #08 pc 007dfc29  /data/app/com.s.time-1/oat/arm/base.odex (offset 0x5ab000) (java.lang.Object com.s.time.Render$Render.doInBackground(java.lang.Object[])+92)
01-16 16:38:13.855 389-389/? A/DEBUG:     #09 pc 729f0c13  /data/dalvik-cache/arm/system@framework@boot.oat (offset 0x1f66000)

@saudet
Copy link
Member

saudet commented Jan 16, 2017

@peter9870 The same code works fine with Java SE on the desktop, right?

@pgfsim
Copy link

pgfsim commented Jan 17, 2017

@saudet Actually I think ParcelFileDescriptor and DocumentFile are unique to Android so it's not possible to have the same code tested on Java SE. However I saw your test file says mp4 is not a streamable format and you used matroska. So using matroska the file actually gets written to but is unplayable as it has a frame rate of 1000 fps and 0 bit rate despite setting the options on the recorder.

@saudet
Copy link
Member

saudet commented Jan 22, 2017

@peter9870 Sounds like a bug in FFmpeg?

@anonym24
Copy link

anonym24 commented Nov 22, 2017

So is it not possible to write to Removable MicroSD Card yet?

I tried

// dir (from intent picker, got it onActivityResult)

DocumentFile newFile = dir.createFile("mp4", "test);

Log.d(TAG, "newFile.canWrite() + " " + newFile.canRead());
// it returns true, true - so I can write and read my newFile

try {
    ParcelFileDescriptor pfd = mContext.getContentResolver().openFileDescriptor(newFile.getUri(),"w");
    mOutputStream = new FileOutputStream(pfd.getFileDescriptor());

    mFrameRecorder = new FFmpegFrameRecorder(mOutputStream, videoWidth, videoHeight, 0);
	...

But I get next error when I start recording A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 12262 (Thread-13250)

@anonym24
Copy link

anonym24 commented Nov 22, 2017

I tried #645 (comment)
it worked with "mastorka" and avutil.AV_PIX_FMT_YUV420P but seeking (changing current position) doesn't work, popular MX Player video player for Android cannot determine video length (in time):

screenshot_2017-11-22-17-17-11-099_com mxtech videoplayer pro

Bad it doesn't work with mp4. (mFrameRecorder.setFormat("mp4");)

Is there any other solutions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants