Android mjpeg stream to Video MP4 - android

I have a ip camera that gives 30 frames mjpeg per second. I want to record that frames to a mp4 file. I have already a library that record it to avi file but its not preferred. I try to convert video to mp4 after record it avi but its a bit slower.
Can you help please

here you go https://github.com/bytedeco/javacv
Android Sample: https://github.com/bytedeco/sample-projects/tree/master/JavaCV-android-example
FFmpegFrameGrabber g = new FFmpegFrameGrabber("textures/video/anim.mp4");
g.start();
for (int i = 0 ; i < 30 ; i++) {
ImageIO.write(g.grab().getBufferedImage(), "png", new File("frame-dump/video-frame-" + System.currentTimeMillis() + ".png"));
}
g.stop();

Related

Add second audio track to MediaMuxer

I have a video file .mp4 - video track only.
I'm using MediaExtractor and MediaMuxer to add audio file.
this Works good.
On the processed file i want to add another audio track.
So i'm using again MediaExtractor and MediaMuxer to kind of copy the file, (Creating video and audio tracks, reading [extractor] and writing [muxer]). In addition i'm trying to add the second audio track to the muxer. but this throws the error Failed to add the track to the muxer.
in this link we can see that muxer does not support multiple tracks.
Code From the link:
// Throws exception b/c 2 audio tracks were added.
muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
muxer.addTrack(MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 1));
try {
muxer.addTrack(MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 1));
fail("should throw IllegalStateException.");
} catch (IllegalStateException e) {
// expected
}
Is there other way to do it ?
Elegant way ?
BTW, i'm trying to avoid using 3rd parties - like ffmpeg or so.. But if would be my only solution...
--EDIT--
Relevant piece of my code
MediaMuxer muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(videoAndAudioFile);
for (int currTrackIdx = 0; currTrackIdx < extractor.getTrackCount(); currTrackIdx++) {
MediaFormat trackFormat = extractor.getTrackFormat(currTrackIdx);
tracksIdx.add(muxer.addTrack(trackFormat));
}
MediaExtractor extractor2 = new MediaExtractor();
extractor2.setDataSource(secondAudioFile);
MediaFormat trackFormat = extractor2.getTrackFormat(0);
tracksIdx.add(muxer.addTrack(trackFormat)); // Crashes here
For someone who reaches here, I found this official doc at link. Muxing Multiple Video/Audio Tracks seems not supported in old API versions and even restricted in the latest version.

MediaExtractor returns wrong number of tracks?

I'm trying to build a player that plays mpeg2-ts stream with 2 audio tracks using MediaCodec and MediaExtractor. When I set the URL to the extractor: extractor.setDataSource(URL) int the Logcat I can see that the framework has found the 2 audio tracks:
But afterwards I call:
int trackCount = extractor.getTrackCount();
for (int i = 0; i < track_count; i++){
format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("video/")) ...
if (mime.startsWith("audio/")) ...
}
trackCount aways equals 2(1 audio track & 1 video track). What am I doing wrong?
You're not doing anything wrong - it just seems that the MPEG2TSExtractor class (the actual implementation behind MediaExtractor for mpeg2 ts files) only supports one audio stream and one video stream.
See e.g. the init method in https://android.googlesource.com/platform/frameworks/av/+/1a9c3954a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp (lines 156-193). So if you need to demux any mpeg2 ts streams with multiple audio streams, you basically need to bundle a demuxer of your own.

extract all video frames in Android

I recorded a Video for limited time. Now i want to fetch all frames of video. I am using the below code and by using it i am able to get frames but i am not getting all video frames. 3 to 4 frames are repeated then i got a different frame. But as we all know we can get 25- 30 frames in a second to display smooth video. How to get all frames.
for (int i = 0; i < 30; i++) {
Bitmap bArray = mediaMetadataRetriever.getFrameAtTime(
1000000 * i,
MediaMetadataRetriever.OPTION_CLOSEST);
savebitmap(bArray, 33333 * i);
}
I don't want to use NDK. I got this link don't know what should be the value for "argb8888". I am getting error here. Can anyone explain how to do it.
Getting frames from Video Image in Android
I faced the same problem before and the Android's MediaMetadataRetriever seems not appropriated for this task since it doesn't have a good precision.
I used a library called "FFmpegMediaMetadataRetriever" in android studio:
Add this line in your build.graddle under module app:
compile 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.14'
Rebuild your project.
Use the FFmpegMediaMetadataRetriever class to grab frames with higher
precision:
FFmpegMediaMetadataRetriever med = new FFmpegMediaMetadataRetriever();
med.setDataSource("your data source");
and in your loop you can grab frame using:
Bitmap bmp = med.getFrameAtTime(i*1000000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
To get image frames from video we can use ffmpeg.For integrating FFmpeg in android we can use precompiled libraries like ffmpeg-android.
To extract image frames from a video we can use below command
String[] complexCommand = {"-y", "-i", inputFileAbsolutePath, "-an",
"-r", "1/2", "-ss", "" + startMs / 1000, "-t", "" + (endMs - startMs)
/ 1000, outputFileAbsolutePath};
Here,
-y
Overwrite output files
-i
ffmpeg reads from an arbitrary number of input “files” specified by the -i option
-an
Disable audio recording.
-r
Set frame rate
-ss
seeks to position
-t
limit the duration of data read from the input file
Here in place of inputFileAbsolutePath you have to specify the absolute path of video file from which you want to extract images.
For complete code check out this on my repository .Inside extractImagesVideo() method I am running command for extracting images from video.
For complete tutorial regarding integration of ffmpeg library and using ffmpeg commands to edit videos, check out this post which I have written on my blog.
You need to do :
Decode the video.
Present the decoded images at least as fast as 24 images / second. I
suppose you can skip this step.
Save the decoded images.
It appears that decoding the video would be the most challenging step. People and companies have spent years developing codecs (encoder / decoder) for various video formats.
Use this library JMF for FFMPEG.

Convert video to audio using FFMPEG with android native c

I have integrated FFMPEG into my application and I want to convert videos to audio files,
But I want to do it using native implementation , (JNI) I don't want to use ffmpeg scripts ,
I have already tried this
You can't convert video to audio. You can however extract and only store the audio sub-streams of an AVFormatContext. Pseudocode:
// look for the first auid substream, and save its index:
for (size_t i = 0; i < AvFormatContextInstance->nb_streams; ++i)
if (AvFormatContextInstance->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
streamindex = i;
Now all you need to do is discard all other streams on other indexes and save AVPackets from the recognized audio stream.

How to create mp4 file from h264 encoded frames on android?

I have some h264 frames already encoded with android encoder. Now i want to create and write them one by one to the mp4 file. Please advise how to do this on android in Java. I don't want to use OpenCV or native code.
mp4-parser can't do this as i understand
navite MPEG4Writer is too complicated to use
Wondering why such a common and very useful thing as mp4 writer NOT FROM CAMERA is not implemented in android
You may use my mp4parser project. You can mux H264 and AAC in pure Java with it:
H264TrackImpl h264Track = new H264TrackImpl(new FileInputStream("raw.h264").getChannel());
Movie m = new Movie();
m.addTrack(h264Track);
IsoFile out = new DefaultMp4Builder().build(m);
FileOutputStream fos = new FileOutputStream(new File("h264_output.mp4"));
out.getBox(fos.getChannel());
fos.close();

Categories

Resources