Fix 3GP file after streaming from Android Media Recorder

前端 未结 2 568
天涯浪人
天涯浪人 2020-12-28 10:13

I am trying to stream video from android camera through local unix socket and write file from stream to sdcard. Everything works fine, except file is not playable with any p

相关标签:
2条回答
  • 2020-12-28 10:20

    What you need to understand is that mp4 is not a live streamable format. hence there is no way you will be able to hack anyway around to make it live streamable. The header [moov atom] is written at the end. Android creates a in memory table of frame sizes and other parameters which it then writes at the begining of the file at the end of recording because of which it needs the seekability of the file handle. [which a socket is not]

    If you are writing encrypted content to the disk and you want to do it so that nobody can play the file you don't have to encrypt the whole file. You just have to encrypt the header and the entire file is unplayable.

    If you desperately need full file encoding because you are not convinced of my previous para then use something like ffmpeg to do the encoding. Modify it give you encrypted output itself and save it to hard disk again - removes the socket part again.

    There is no way you can do live streaming of mp4 files in android. I have seen tons of people trying it in vain and if you understand video/formats there is not way you can do it. mp4 is not designed for live streaming. Unless you know your frame sizes in advance [which you don't] and the exact length of encoding [which you most probably don;t] you cannot pre-create the header.

    ps. mp4 and 3gp are cousins so the same thing applies.

    Many people confuse live streaming with http pd and pseudo streaming. Live streaming means I do not have the whole file, it is being created and also being streamed on the fly. http pd and pseudo streaming take place with files that are fully available.

    EDIT:

    If your aim is to encrypt the recorded file before storing in sdcard you need encoder support. This implies getting your own encoder in there. Take ffmpeg, cross compile it to android. Write a small JNI interface for your application. Get this up first without encryption. Once done, where ffmpeg fwrites the stream, add your encryption module. Same thing while decoding. Y3ng creation. This is the cleanest way to do it.

    EDIT 2: See spydroid to get some of the features for you. There are similar ones out there.

    EDIT 3: To improve the quality of the answer I am explaining an imperfect workaround also given by other answers:

    One can still stream the AV by parsing the mp4 as it gets generated and sending the elementary streams seperately over a socket. The only issue you will face is that you will not get perfect AV sync as you do not know the exact AV sample timestamps. Only android knows that and it writes that in the mp4 header at the end. So no good for you. You have to be making an assumption on perfect sampling rate of video frames and your audio will have to be amr to assume 20ms packets. In other audio cases you will start seeing drift in long runs [especially where you start having scenes of high motion]. This is because each audio packet generated does not correspond to a fixed time duration [except for amr and other speech codecs]

    0 讨论(0)
  • 2020-12-28 10:31

    First of all, it's not very clear what you are trying to do.

    Do you want just to save a video programmatically to a playable file? If so, you just need to use file descriptor instead of unix socket. This API of MediaRecord was designed to work with a file (not unix socket), precisely for the reason of random access. So, my first advise would be to use file descriptor and you will get correct file at the end of recording.

    You can get examples here: How can I capture a video recording on Android?

    In the case, if you are trying to write an application which streams video from device, you will need to parse the stream in a realime, divide it by frames and send frames separately. And the most complex part is parsing the stream (some video codecs, as example H263 can be parsed and other can't be, especially if the data is interleaved with the audio).

    I believe one of these two projects implements such functionality: http://sipdroid.org/ http://code.google.com/p/imsdroid/

    0 讨论(0)
提交回复
热议问题