I have used xuggler to play audio files other than wav,au,aiff. Since xuggler performs audio decoding at low level it is very hard to write a method that both forwards and rewinds the audio being played . ( while decoding xuggler analyzes each data packet and then sends it to play)
One way could be read bunch of packets at a time and then send the next packet to play.This way the effect of forwarding audio can be felt . But i don't know how to implement this method Moreover this is not the best way i can forward the data.
Are there any direct methods to forward and rewind audio ? If not direct what is the algorithm , steps to do this ?
Have you looked at the seekKeyFrame() method in IContainer? See here. On seek, you could just flush the dataline and then on execution of the method the container should jump to the given location.
If you want to do it by a percentage call, then getDuration() gets the entire length of the stream (if available.) You can then work out accurate timestamps from there.
Related
I'm building an icecast source in Java and I'm using libshout2 to transmit the stream.
My audio sometimes (at some large intervals) has glitches for an instant. I assume it relates to the stream rate which libshout is (should be) taking care of.
I've tried
transmitting the mp3 file as is (in chunks of course).
transmitting the frames only
transmitting the encoded samples (frame withought the frame header)
In all cases, over some large time period there is a glitch coming out.
So, I am wondering what could it be? What exactly should my stream sent to libshout2 should contain?
In the documentation they claim that it deals with the data and discards what is not meant to be sent, etc. This would mean, just read the file and send it in... it will handle it... well, it doesn't.
The only way that worked for me was to actually parse the file and eliminate everything except the body of the frames.
I'm a bit stuck on a question actually and i reaaly hope that someone can help me with this issue.
My problem is as follows :
I have a live usb camera with which i'm encoding only the video in h264 in order to send it with RTP over the network to a receiver (my receiver here for test purposes is Ekiga).
After having encoded only the video in h264, i have a byte array.
Now with this byte array, i want to extract the SPS and PPS. I want to get these information for me to be able to send the following sequence when sending frames to the receiver :
SPS => PPS => FRAME 1 (coded slice of an IDR picture) => FRAME 2 (non coded slice of an IDR picture) => FRAME 3 (non coded slice of an IDR picture) => and so on ...
How can i extract those information and i want a JAVA library which can help me? (JCODEC nop docs??!!)
Thanks for your help.
Ronnie
It depends on your encoder. If it is producing annex b stream the sps/pps are most likely the first and second Nalus. Unless it is also producing access unit delimiters in which case it will be second and third. If it is not producing annex b then this data will need to be obtained from the encoders API another way. Either way you will need to parse the stream. You can see more details here.
Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream
One more thing a NALU is NOT the same thing as a frame. A frame can be made up of Many NALs.
Thanks for your help and answer. Well, my researches and works continue (i'm a newbie in this domain) and i have been able to transmit my video to the receiver. The receiver here is Jitsi which i'm using for test purposes.
I've seen too the link which you provided me and from it, i did understand many things which weren't totally clear.
Now, my actual problem is with the quality of the video i am receiving in Jitsi. In fact, i'm using Xuggler for encoding my orginal video (streaming from my webcam) to H264 format. When Xuggler encode my video, i can now see the correct SPS, PPS and SEI headers and you are right i can notice too many NALs which make up my frame to be transmitted over the network.
I think that it would be better to use another library than Xuggler but there comes my real problem. JCodec, there's no documentations and from what i have read, it's a bit slow in processing H264 videos.
Can you please guide me in the choice of a good library which can help me in encoding and decoding H264 video streams?
Does anyone know a library in Java which can do that for me and some documentations associated with this library?
Thanks for your help.
Ronnie
I'm using a AudioInputStream to feed bytes to a SourceDataLine to play a PCM file. I want to give the user the ability to move a slider to jump to some point in the file.
Issues I'm having:
markSupported() returns false on my AudioInputStream. So I
cannot use my initial approach to call reset() then skip() (which
I already thought was kind of ugly...)
I would really prefer not to tear down the InputStream and create a new one just to jump to a position prior to my current mark.
SourceLineData.getLongFramePosition() does not seem to be very reliable... I know it has a buffer, but even if account for the bytes left in the buffer, i do not understand the behavior
I have considered using a Memory-Mapped File to feed bytes to the line that way I can jump wherever I want, but I don't want to add complexity to the function if I don't have to. Is there a good way to do this that I'm missing? also can anyone explain what the frame number returned by getLongFramePosition() actually means? is it number of frames passed through speakers (does not appear to be)?
Did the BigClip work for you?
If not, here's something that could work. Warning, it is a little convoluted.
http://hexara.com/VSL/VSL2.htm
With this Applet, you can load a wav -- I've loaded wavs longer than 5 minutes and it has worked fine, but audio data does take up a lot of RAM.
Once the WAV is loaded, you can mouse to any point and playback via holding the mouse down and dragging. Obviously, that's not exactly what YOU want to do, since you want to play back from a point, and not worry about dragging or dragging speed. But the path I take to get the data in a playable state should still work for you.
If you have a working AudioInputStream and AudioFileFormat, you can set up an internal array and read the data directly into it. The audio file format gives you the encoding and the length in frames which you can use to calculate your array dimension.
Then, make a TargetDataLine that gets its audio data from the array you made. A TDL has to have a variable that marks where the next read will start. You can use your JSlider to change the contents of that variable to point to whatever frame you want.
If you don't have a working AudioInputStream, there are ways to get one...but it is more convoluted, involving ByteArrayOutput & Input Stream objects. Probably no need to go there. (I use them to read client data in the above Applet.)
As to your question about the current Frame location, the key problem is that the JVM processes audio data in chunks, and it tends to run ahead of what is heard in bursts. I banged my head against this problem for a long while, then came up with this:
http://www.java-gaming.org/index.php/topic,24605.0.html
The cleanest way I could come up with was to use a FileChannel to read the bytes into the SourceDataLine this way based on the user moving a slider I could determine the byte position in the file (making sure to adjust or round it to line up with a frame) and then set that position in the FileChannel and then continue playback. I flushed the line when this happened to keep from playing remaining bytes.
I want to record own voice or any through mic(In any way) into a file in my project and want to read later and listen to it.How can i do this? Anyone reply me please.
http://developer.android.com/guide/topics/media/index.html
About 3/4 the way down the page you'll see
Performing Audio Capture
Audio capture from the device is a bit more complicated than audio and video playback, but still fairly simple:
Create a new instance of android.media.MediaRecorder.
Set the audio source using MediaRecorder.setAudioSource(). You will probably want to use MediaRecorder.AudioSource.MIC.
Set output file format using MediaRecorder.setOutputFormat().
Set output file name using MediaRecorder.setOutputFile().
Set the audio encoder using MediaRecorder.setAudioEncoder().
Call MediaRecorder.prepare() on the MediaRecorder instance.
To start audio capture, call MediaRecorder.start().
To stop audio capture, call MediaRecorder.stop().
When you are done with the MediaRecorder instance, call MediaRecorder.release() on it. Calling MediaRecorder.release() is always recommended to free the resource immediately.
Followed by code showing exactly how to store audio input and play it back, hope this helps. (I tried to paste the code here but pasting from android's guides is difficult)
I need to split mpeg4 video stream (actually from android video camera) to send it through RTP.
The specification is little large for quick reference.
I wonder if there any example/open source code for mpeg4 packetization?
Thanks for any help !
Mpeg4 file format is also called ISO/IEC 14496-14. Google it any you will find specifications.
However, what you are trying to do (RTP publisher) will be hard for the following reasons:
Mpeg4 has header at the end of the file. Which means header will be written out only when video stream is finished. Since you want to do real time video streaming you will need to guess where audio and video packets start/end. This will not be the same on all Android devices as they might use different video sizes and codec parameters. So your code will be device-dependent and you'll need to support and test many different devices.
Some devices do not flush video data to file in regular intervals. Some only flush once a minute or so. This will break your real-time stream.
There is no example code. I know because I looked. There are a few companies that do something similar, but mainly they skip RTP. Instead they progressively upload the file to their own server and then implement video/audio stream "chopping" and then insert it into their video/transcoder backend. I used to work for one of those companies and that's how we did it. AFAIK competition took similar approaches. The upside is that all complexity is on server an you do not need to update clients when something breaks or new devices arrive on the market.