bytedeco/javacv

Pause live streaming problem

Open

#936 opened on Mar 8, 2018

View on GitHub
 (23 comments) (0 reactions) (0 assignees)Java (1,583 forks)batch import
help wantedquestion

Repository metrics

Stars
 (6,985 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Hi, i have live streaming use RTMP , when i work with audio only everything is OK , but when i use video + audio there a problem after pause and start streaming. it delay and not working right.

this is my code

    	audio_thread = new Thread(new Runnable() {			
			@Override
			public void run() 
			{
				
				AudioFormat audioFormat = new AudioFormat(SAMPLE_RATE , 16 , AUDIO_CHANNEL  , true , false );
				// Get TargetDataLine with that format
                Mixer.Info[] minfoSet = AudioSystem.getMixerInfo();
                Mixer mixer = AudioSystem.getMixer(minfoSet[AUDIO_DEVICE_INDEX]);
                DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
                
                try
                {
                	
                	final TargetDataLine line = (TargetDataLine)AudioSystem.getLine(dataLineInfo);
                    line.open(audioFormat);
                    line.start();
                    
                    final int sampleRate = (int) audioFormat.getSampleRate();
                    final int numChannels = audioFormat.getChannels();
                    
                    
                    // Let's initialize our audio buffer...
                    int audioBufferSize = sampleRate * numChannels;
                    final byte[] audioBytes = new byte[audioBufferSize];
                    
                    ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
                    exec.scheduleAtFixedRate(new Runnable() {
                        @Override
                        public void run()
                        {
                            try
                            {
                                // Read from the line... non-blocking
                                int nBytesRead = 0;
                                while (nBytesRead == 0) {
                                    nBytesRead = line.read(audioBytes, 0, line.available());
                                }

                                // Since we specified 16 bits in the AudioFormat,
                                // we need to convert our read byte[] to short[]
                                // (see source from FFmpegFrameRecorder.recordSamples for AV_SAMPLE_FMT_S16)
                                // Let's initialize our short[] array
                                int nSamplesRead = nBytesRead / 2;
                                short[] samples = new short[nSamplesRead];

                                // Let's wrap our short[] into a ShortBuffer and
                                // pass it to recordSamples
                                ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(samples);
                                ShortBuffer sBuff = ShortBuffer.wrap(samples, 0, nSamplesRead);

                                /*if (startTime == 0)
                                    startTime = System.currentTimeMillis();
                                
                                
                                // Create timestamp for this frame
                                videoTS = 1000 * (System.currentTimeMillis() - startTime);

                                // Check for AV drift
                                if (videoTS > recorder.getTimestamp())
                                {
                                    System.out.println("timestamp : " + videoTS + " : "+ recorder.getTimestamp() + " -> " + (videoTS - recorder.getTimestamp()));

                                    // We tell the recorder to write this frame at this timestamp
                                    recorder.setTimestamp(videoTS);
                                }*/
                                
                                // recorder is instance of
                                // org.bytedeco.javacv.FFmpegFrameRecorder
                                if(streaming)
                                	recorder.recordSamples(sampleRate, numChannels, sBuff);
                            } 
                            catch (org.bytedeco.javacv.FrameRecorder.Exception e)
                            {
                                e.printStackTrace();
                            }
                        }
                    }, 0, (long) 1000 / FRAME_RATE , TimeUnit.MILLISECONDS);
                    // (long) 1000 / FRAME_RATE
                	
                }catch(java.lang.Exception e)
                {
                	System.err.println("error in sound " + e.getLocalizedMessage());
                }
			}
		});
    	    	    	
    	video_thread = new Thread(new Runnable() {			
			@Override
			public void run() {
				
				ScheduledThreadPoolExecutor video_loop = new ScheduledThreadPoolExecutor(1);
				video_loop.scheduleAtFixedRate(new Runnable() {					
					@Override
					public void run() {
						
						try {
							
							if(streaming)
				            {
								capturedFrame = grabber.grab();
								
								if(cFrame.isVisible())
								{
									 cFrame.showImage(capturedFrame);
								}
								
								
								if (startTime == 0)
						            startTime = System.currentTimeMillis();

						        // Create timestamp for this frame
						        videoTS = 1000 * (System.currentTimeMillis() - startTime);
						        
						        // Check for AV drift
						        if (videoTS > recorder.getTimestamp())
						        {
						            System.out.println( "Lip-flap correction: "  + videoTS + " : "  + recorder.getTimestamp() + " -> " + (videoTS - recorder.getTimestamp()));

						            // We tell the recorder to write this frame at this timestamp
						            recorder.setTimestamp(videoTS);
						        }
						        
						        // Send the frame to the org.bytedeco.javacv.FFmpegFrameRecorder
						        recorder.record(capturedFrame);
				            }
							
							
						} catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					}
				}, 0 , (long) 1.5 , TimeUnit.MILLISECONDS);
			}
		});
    	
    	audio_thread.start();
    	
    	if(camFound)
    		video_thread.start();

this is how i pause the stream

    void stop()
    {
    	try {
			
    		streaming = false;

    		if(cFrame != null)
    			cFrame.setVisible(false);			

			
		} catch (java.lang.Exception e) {

			e.printStackTrace();
		}
    }
    
    void start() 
    {
    	startTime = System.currentTimeMillis();
    	System.out.println("video TS : " + videoTS + " timeStamp: " + startTime);
		
    	if(cFrame != null)
    	{
    		if(camFound)
    			cFrame.setVisible(true);
    		
    	}
    	
    	
    	streaming = true;
    }

Contributor guide