{"action":"created","issue":{"url":"https://api.github.com/repos/bytedeco/javacv/issues/936","repository_url":"https://api.github.com/repos/bytedeco/javacv","labels_url":"https://api.github.com/repos/bytedeco/javacv/issues/936/labels{/name}","comments_url":"https://api.github.com/repos/bytedeco/javacv/issues/936/comments","events_url":"https://api.github.com/repos/bytedeco/javacv/issues/936/events","html_url":"https://github.com/bytedeco/javacv/issues/936","id":303314127,"number":936,"title":"Pause live streaming problem","user":{"login":"zchacker","id":4500681,"avatar_url":"https://avatars2.githubusercontent.com/u/4500681?v=4","gravatar_id":"","url":"https://api.github.com/users/zchacker","html_url":"https://github.com/zchacker","followers_url":"https://api.github.com/users/zchacker/followers","following_url":"https://api.github.com/users/zchacker/following{/other_user}","gists_url":"https://api.github.com/users/zchacker/gists{/gist_id}","starred_url":"https://api.github.com/users/zchacker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zchacker/subscriptions","organizations_url":"https://api.github.com/users/zchacker/orgs","repos_url":"https://api.github.com/users/zchacker/repos","events_url":"https://api.github.com/users/zchacker/events{/privacy}","received_events_url":"https://api.github.com/users/zchacker/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":10,"created_at":"2018-03-08T00:43:39Z","updated_at":"2018-03-08T22:49:19Z","closed_at":null,"author_association":"NONE","body":"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.\r\n\r\nthis is my code \r\n \t\r\n```\r\n    \taudio_thread = new Thread(new Runnable() {\t\t\t\r\n\t\t\t@Override\r\n\t\t\tpublic void run() \r\n\t\t\t{\r\n\t\t\t\t\r\n\t\t\t\tAudioFormat audioFormat = new AudioFormat(SAMPLE_RATE , 16 , AUDIO_CHANNEL  , true , false );\r\n\t\t\t\t// Get TargetDataLine with that format\r\n                Mixer.Info[] minfoSet = AudioSystem.getMixerInfo();\r\n                Mixer mixer = AudioSystem.getMixer(minfoSet[AUDIO_DEVICE_INDEX]);\r\n                DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);\r\n                \r\n                try\r\n                {\r\n                \t\r\n                \tfinal TargetDataLine line = (TargetDataLine)AudioSystem.getLine(dataLineInfo);\r\n                    line.open(audioFormat);\r\n                    line.start();\r\n                    \r\n                    final int sampleRate = (int) audioFormat.getSampleRate();\r\n                    final int numChannels = audioFormat.getChannels();\r\n                    \r\n                    \r\n                    // Let's initialize our audio buffer...\r\n                    int audioBufferSize = sampleRate * numChannels;\r\n                    final byte[] audioBytes = new byte[audioBufferSize];\r\n                    \r\n                    ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);\r\n                    exec.scheduleAtFixedRate(new Runnable() {\r\n                        @Override\r\n                        public void run()\r\n                        {\r\n                            try\r\n                            {\r\n                                // Read from the line... non-blocking\r\n                                int nBytesRead = 0;\r\n                                while (nBytesRead == 0) {\r\n                                    nBytesRead = line.read(audioBytes, 0, line.available());\r\n                                }\r\n\r\n                                // Since we specified 16 bits in the AudioFormat,\r\n                                // we need to convert our read byte[] to short[]\r\n                                // (see source from FFmpegFrameRecorder.recordSamples for AV_SAMPLE_FMT_S16)\r\n                                // Let's initialize our short[] array\r\n                                int nSamplesRead = nBytesRead / 2;\r\n                                short[] samples = new short[nSamplesRead];\r\n\r\n                                // Let's wrap our short[] into a ShortBuffer and\r\n                                // pass it to recordSamples\r\n                                ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(samples);\r\n                                ShortBuffer sBuff = ShortBuffer.wrap(samples, 0, nSamplesRead);\r\n\r\n                                /*if (startTime == 0)\r\n                                    startTime = System.currentTimeMillis();\r\n                                \r\n                                \r\n                                // Create timestamp for this frame\r\n                                videoTS = 1000 * (System.currentTimeMillis() - startTime);\r\n\r\n                                // Check for AV drift\r\n                                if (videoTS > recorder.getTimestamp())\r\n                                {\r\n                                    System.out.println(\"timestamp : \" + videoTS + \" : \"+ recorder.getTimestamp() + \" -> \" + (videoTS - recorder.getTimestamp()));\r\n\r\n                                    // We tell the recorder to write this frame at this timestamp\r\n                                    recorder.setTimestamp(videoTS);\r\n                                }*/\r\n                                \r\n                                // recorder is instance of\r\n                                // org.bytedeco.javacv.FFmpegFrameRecorder\r\n                                if(streaming)\r\n                                \trecorder.recordSamples(sampleRate, numChannels, sBuff);\r\n                            } \r\n                            catch (org.bytedeco.javacv.FrameRecorder.Exception e)\r\n                            {\r\n                                e.printStackTrace();\r\n                            }\r\n                        }\r\n                    }, 0, (long) 1000 / FRAME_RATE , TimeUnit.MILLISECONDS);\r\n                    // (long) 1000 / FRAME_RATE\r\n                \t\r\n                }catch(java.lang.Exception e)\r\n                {\r\n                \tSystem.err.println(\"error in sound \" + e.getLocalizedMessage());\r\n                }\r\n\t\t\t}\r\n\t\t});\r\n    \t    \t    \t\r\n    \tvideo_thread = new Thread(new Runnable() {\t\t\t\r\n\t\t\t@Override\r\n\t\t\tpublic void run() {\r\n\t\t\t\t\r\n\t\t\t\tScheduledThreadPoolExecutor video_loop = new ScheduledThreadPoolExecutor(1);\r\n\t\t\t\tvideo_loop.scheduleAtFixedRate(new Runnable() {\t\t\t\t\t\r\n\t\t\t\t\t@Override\r\n\t\t\t\t\tpublic void run() {\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tif(streaming)\r\n\t\t\t\t            {\r\n\t\t\t\t\t\t\t\tcapturedFrame = grabber.grab();\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\tif(cFrame.isVisible())\r\n\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\t cFrame.showImage(capturedFrame);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\tif (startTime == 0)\r\n\t\t\t\t\t\t            startTime = System.currentTimeMillis();\r\n\r\n\t\t\t\t\t\t        // Create timestamp for this frame\r\n\t\t\t\t\t\t        videoTS = 1000 * (System.currentTimeMillis() - startTime);\r\n\t\t\t\t\t\t        \r\n\t\t\t\t\t\t        // Check for AV drift\r\n\t\t\t\t\t\t        if (videoTS > recorder.getTimestamp())\r\n\t\t\t\t\t\t        {\r\n\t\t\t\t\t\t            System.out.println( \"Lip-flap correction: \"  + videoTS + \" : \"  + recorder.getTimestamp() + \" -> \" + (videoTS - recorder.getTimestamp()));\r\n\r\n\t\t\t\t\t\t            // We tell the recorder to write this frame at this timestamp\r\n\t\t\t\t\t\t            recorder.setTimestamp(videoTS);\r\n\t\t\t\t\t\t        }\r\n\t\t\t\t\t\t        \r\n\t\t\t\t\t\t        // Send the frame to the org.bytedeco.javacv.FFmpegFrameRecorder\r\n\t\t\t\t\t\t        recorder.record(capturedFrame);\r\n\t\t\t\t            }\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t} catch (org.bytedeco.javacv.FrameRecorder.Exception e) {\r\n\t\t\t\t\t\t\t// TODO Auto-generated catch block\r\n\t\t\t\t\t\t\te.printStackTrace();\r\n\t\t\t\t\t\t} catch (Exception e) {\r\n\t\t\t\t\t\t\t// TODO Auto-generated catch block\r\n\t\t\t\t\t\t\te.printStackTrace();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t}\r\n\t\t\t\t}, 0 , (long) 1.5 , TimeUnit.MILLISECONDS);\r\n\t\t\t}\r\n\t\t});\r\n    \t\r\n    \taudio_thread.start();\r\n    \t\r\n    \tif(camFound)\r\n    \t\tvideo_thread.start();\r\n```\r\n\r\nthis is how i pause the stream\r\n\r\n\r\n\r\n```\r\n    void stop()\r\n    {\r\n    \ttry {\r\n\t\t\t\r\n    \t\tstreaming = false;\r\n\r\n    \t\tif(cFrame != null)\r\n    \t\t\tcFrame.setVisible(false);\t\t\t\r\n\r\n\t\t\t\r\n\t\t} catch (java.lang.Exception e) {\r\n\r\n\t\t\te.printStackTrace();\r\n\t\t}\r\n    }\r\n    \r\n    void start() \r\n    {\r\n    \tstartTime = System.currentTimeMillis();\r\n    \tSystem.out.println(\"video TS : \" + videoTS + \" timeStamp: \" + startTime);\r\n\t\t\r\n    \tif(cFrame != null)\r\n    \t{\r\n    \t\tif(camFound)\r\n    \t\t\tcFrame.setVisible(true);\r\n    \t\t\r\n    \t}\r\n    \t\r\n    \t\r\n    \tstreaming = true;\r\n    }\r\n```\r\n    \r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/bytedeco/javacv/issues/comments/371651961","html_url":"https://github.com/bytedeco/javacv/issues/936#issuecomment-371651961","issue_url":"https://api.github.com/repos/bytedeco/javacv/issues/936","id":371651961,"user":{"login":"saudet","id":3328023,"avatar_url":"https://avatars1.githubusercontent.com/u/3328023?v=4","gravatar_id":"","url":"https://api.github.com/users/saudet","html_url":"https://github.com/saudet","followers_url":"https://api.github.com/users/saudet/followers","following_url":"https://api.github.com/users/saudet/following{/other_user}","gists_url":"https://api.github.com/users/saudet/gists{/gist_id}","starred_url":"https://api.github.com/users/saudet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saudet/subscriptions","organizations_url":"https://api.github.com/users/saudet/orgs","repos_url":"https://api.github.com/users/saudet/repos","events_url":"https://api.github.com/users/saudet/events{/privacy}","received_events_url":"https://api.github.com/users/saudet/received_events","type":"User","site_admin":false},"created_at":"2018-03-08T22:49:19Z","updated_at":"2018-03-08T22:49:19Z","author_association":"OWNER","body":"So, please read the documentation of the RMTP module of Nginx, and let me know what it needs to resynchronize streams!"}}
{"actor":{"display_login":"saudet"}}