diff --git a/plugins/hal-nvr/src/se/hal/plugin/nvr/rtsp/RTSPCameraRecorder.java b/plugins/hal-nvr/src/se/hal/plugin/nvr/rtsp/RTSPCameraRecorder.java index 594aeac7..ff352dbc 100644 --- a/plugins/hal-nvr/src/se/hal/plugin/nvr/rtsp/RTSPCameraRecorder.java +++ b/plugins/hal-nvr/src/se/hal/plugin/nvr/rtsp/RTSPCameraRecorder.java @@ -43,81 +43,90 @@ public class RTSPCameraRecorder implements Runnable { public void run() { logger.info("Starting up RTSP Stream recording thread for: " + camera.getRtspUrl()); - try { - new File(storagePath).mkdirs(); + while (camera != null) { + try { + new File(storagePath).mkdirs(); - // ---------------------------------- - // Setup commandline - // ---------------------------------- + // ---------------------------------- + // Setup commandline + // ---------------------------------- - FFmpegInput ffmpegInput = new FFmpegInput(camera.getRtspUrl()); + FFmpegInput ffmpegInput = new FFmpegInput(camera.getRtspUrl()); - //FFmpegOutput ffmpegOutput = new FFmpegOutput(storagePath + File.separator + "stream.mp4"); - FFmpegOutput ffmpegOutput = new FFmpegOutput(new File(storagePath, "stream_%v/stream.m3u8").getPath()); - /*ffmpegOutput.addAdditionalArg("-filter_complex \"[0:v]split=3[v1][v2][v3]; [v1]copy[v1out]; [v2]scale=w=1280:h=720[v2out]; [v3]scale=w=640:h=360[v3out]\"", - "-map [v1out] -c:v:0 libx264 -x264-params \"nal-hrd=cbr:force-cfr=1\" -b:v:0 5M -maxrate:v:0 5M -minrate:v:0 5M -bufsize:v:0 10M -preset veryfast -g 25 -sc_threshold 0", - "-map [v2out] -c:v:1 libx264 -x264-params \"nal-hrd=cbr:force-cfr=1\" -b:v:1 3M -maxrate:v:1 3M -minrate:v:1 3M -bufsize:v:1 3M -preset veryfast -g 25 -sc_threshold 0", - "-map [v3out] -c:v:2 libx264 -x264-params \"nal-hrd=cbr:force-cfr=1\" -b:v:2 1M -maxrate:v:2 1M -minrate:v:2 1M -bufsize:v:2 1M -preset veryfast -g 25 -sc_threshold 0", - "-map a:0 -c:a:0 aac -b:a:0 96k -ac 2", - "-map a:0 -c:a:1 aac -b:a:1 96k -ac 2", - "-map a:0 -c:a:2 aac -b:a:2 48k -ac 2", - "-var_stream_map \"v:0,a:0,name:Source v:1,a:1,name:720p v:2,a:2,name:360p\"" - );*/ - ffmpegOutput.addAdditionalArg( - "-c:v:0 libx264 -x264-params \"nal-hrd=cbr:force-cfr=1\" -b:v:0 5M -maxrate:v:0 5M -minrate:v:0 5M -bufsize:v:0 10M -preset veryfast -g 25 -sc_threshold 0" - ); - ffmpegOutput.addAdditionalArg("-f hls", - "-hls_time 2", // segment length in seconds - //"-hls_playlist_type event", // Do not delete old segments - "-hls_flags independent_segments+delete_segments", - "-hls_segment_type mpegts", - "-hls_segment_filename \"" + new File(storagePath, "stream_%v/data%02d.ts").getPath() + "\"", - "-master_pl_name \"playlist.m3u8\"" - ); + FFmpegOutput ffmpegOutput = new FFmpegOutput(new File(storagePath, "stream_%v/stream.m3u8").getPath()); + /*ffmpegOutput.addAdditionalArg("-filter_complex \"[0:v]split=3[v1][v2][v3]; [v1]copy[v1out]; [v2]scale=w=1280:h=720[v2out]; [v3]scale=w=640:h=360[v3out]\"", + "-map [v1out] -c:v:0 libx264 -x264-params \"nal-hrd=cbr:force-cfr=1\" -b:v:0 5M -maxrate:v:0 5M -minrate:v:0 5M -bufsize:v:0 10M -preset veryfast -g 25 -sc_threshold 0", + "-map [v2out] -c:v:1 libx264 -x264-params \"nal-hrd=cbr:force-cfr=1\" -b:v:1 3M -maxrate:v:1 3M -minrate:v:1 3M -bufsize:v:1 3M -preset veryfast -g 25 -sc_threshold 0", + "-map [v3out] -c:v:2 libx264 -x264-params \"nal-hrd=cbr:force-cfr=1\" -b:v:2 1M -maxrate:v:2 1M -minrate:v:2 1M -bufsize:v:2 1M -preset veryfast -g 25 -sc_threshold 0", + "-map a:0 -c:a:0 aac -b:a:0 96k -ac 2", + "-map a:0 -c:a:1 aac -b:a:1 96k -ac 2", + "-map a:0 -c:a:2 aac -b:a:2 48k -ac 2", + "-var_stream_map \"v:0,a:0,name:Source v:1,a:1,name:720p v:2,a:2,name:360p\"" + );*/ + ffmpegOutput.addAdditionalArg( + "-c:v:0 libx264 -x264-params \"nal-hrd=cbr:force-cfr=1\" -b:v:0 5M -maxrate:v:0 5M -minrate:v:0 5M -bufsize:v:0 10M -preset veryfast -g 25 -sc_threshold 0" + ); + ffmpegOutput.addAdditionalArg("-f hls", + "-hls_time 2", // segment length in seconds + //"-hls_playlist_type event", // Do not delete old segments + "-hls_flags independent_segments+delete_segments", + "-hls_segment_type mpegts", + "-hls_segment_filename \"" + new File(storagePath, "stream_%v/data%02d.ts").getPath() + "\"", + "-master_pl_name \"playlist.m3u8\"" + ); - FFmpeg ffmpeg = new FFmpeg(); - ffmpeg.setLogLevel(FFmpegConstants.FFmpegLogLevel.ERROR); - ffmpeg.addInput(ffmpegInput); - ffmpeg.addOutput(ffmpegOutput); - String cmdParams = ffmpeg.buildCommand(); + FFmpeg ffmpeg = new FFmpeg(); + ffmpeg.setLogLevel(FFmpegConstants.FFmpegLogLevel.ERROR); + ffmpeg.addInput(ffmpegInput); + ffmpeg.addOutput(ffmpegOutput); + String cmdParams = ffmpeg.buildCommand(); - // ---------------------------------- - // Execute command - // ---------------------------------- + // ---------------------------------- + // Execute command + // ---------------------------------- - File cmdPath = OSALBinaryManager.getPath(FFMPEG_BINARY_PATH, "ffmpeg"); + File cmdPath = OSALBinaryManager.getPath(FFMPEG_BINARY_PATH, "ffmpeg"); - String cmd = cmdPath.getParent() + File.separator + cmdParams; - logger.finest("Executing ffmpeg: " + cmd); + String cmd = cmdPath.getParent() + File.separator + cmdParams; + logger.finest("Executing ffmpeg: " + cmd); - Runtime.getRuntime().addShutdownHook(new Thread() { - public void run() { - if (process != null) process.destroyForcibly(); + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + if (process != null) process.destroyForcibly(); + } + }); + + process = Runtime.getRuntime().exec(cmd); + BufferedReader output = new BufferedReader(new InputStreamReader(process.getErrorStream())); + + while (process.isAlive()) { + String line; + while ((line = output.readLine()) != null) { + logger.finest("[Cam: " + camera.getRtspUrl() + "] " + line); + } + + Thread.sleep(1000); } - }); - - process = Runtime.getRuntime().exec(cmd); - BufferedReader output = new BufferedReader(new InputStreamReader(process.getErrorStream())); - - while (process.isAlive()) { - String line; - while ((line = output.readLine()) != null) { - logger.finest("[Cam: " + camera.getRtspUrl() + "] " + line); - } - - Thread.sleep(1000); + output.close(); + } catch (Exception e) { + logger.log(Level.SEVERE, "RTSP Stream recording thread has crashed for: " + camera.getRtspUrl(), e); + } finally { + logger.info("Shutting down RTSP Stream recording thread for: " + camera.getRtspUrl()); + } + + if (camera != null) { + try { + logger.info("Restarting RTSP thread in 3 seconds."); + Thread.sleep(3000); + } catch (InterruptedException e) {} } - output.close(); - } catch (Exception e) { - logger.log(Level.SEVERE, "RTSP Stream recording thread has crashed for: " + camera.getRtspUrl(), e); - } finally { - logger.info("Shutting down RTSP Stream recording thread for: " + camera.getRtspUrl()); } } public void close() { if (process != null) { logger.info("Killing ffmpeg instance."); + camera = null; process.destroy(); } }