diff --git a/src/main/java/io/antmedia/AppSettings.java b/src/main/java/io/antmedia/AppSettings.java index 26403eed8..fd60fb271 100644 --- a/src/main/java/io/antmedia/AppSettings.java +++ b/src/main/java/io/antmedia/AppSettings.java @@ -1093,9 +1093,10 @@ public class AppSettings implements Serializable{ /** * The settings for accepting only time based token subscribers as connections to the streams - * @Deprecated. Please use {@link #enableTimeTokenForPlay} or {@link #enableTimeTokenForPublish} + * @deprecated. Please use {@link #enableTimeTokenForPlay} or {@link #enableTimeTokenForPublish} */ @Value( "${timeTokenSubscriberOnly:${"+SETTINGS_TIME_TOKEN_SUBSCRIBER_ONLY+":false}}" ) + @Deprecated private boolean timeTokenSubscriberOnly; /** * The setting for accepting only time based token(TOTP) subscribers as connections to the streams @@ -1161,9 +1162,10 @@ public class AppSettings implements Serializable{ /** * The path for manually saved used VoDs * Determines the directory to store VOD files. - * @Deprecated use {@link VoDRestService#importVoDs(String)} + * @deprecated use {@link VoDRestService#importVoDs(String)} */ @Value( "${vodFolder:${"+SETTINGS_VOD_FOLDER+":}}" ) + @Deprecated private String vodFolder = ""; /** @@ -1346,41 +1348,69 @@ public class AppSettings implements Serializable{ /** * Name of the encoder to be used in adaptive bitrate, * If there is a GPU, server tries to open h264_nvenc, - * If there is no GPU, server tries to open libx264 by default - * Can be h264_nvenc or libx264. If you set h264_nvenc but it cannot be opened then libx264 will be used, - * Name of the encoder to be used in adaptive bitrate, - * If there is a GPU, server tries to open h264_nvenc, - * If there is no GPU, server tries to open libx264 by default + * If there is no GPU, server tries to open openh264 by default + * Can be h264_nvenc or openh264. If you set h264_nvenc and then if it cannot be opened, libx264 will be used, */ @Value( "${encoderName:${" + SETTINGS_ENCODING_ENCODER_NAME +":}}") private String encoderName = ""; + + /** + * Encoder specific parameters in key-value mapping way with JSON objects. + * + * Keys should match the encoder names officially in ffmpeg for instance libopenh264, h264_nvenc, vpx, hevc_nvenc + * + * Then you can have a json object like this which includes the parameters for the encoder + * { + * "libopenh264": { + * "profile":"main", + * + * }, + * "vpx": { + * "deadline":"realtime", + * }, + * "h264_nvenc": { + * "preset":"ll" + * } + * } + */ + @Value("${encoderParameters:{}}") + private Map> encoderParameters = new HashMap<>(); /** * Encoder's preset value in adaptive bitrate * Libx264 presets are there * https://trac.ffmpeg.org/wiki/Encode/H.264 * Ant Media Server uses "veryfast" by default + * + * @deprecated use {@link #encoderParameters} * */ @Value("${encoderPreset:${" + SETTINGS_ENCODING_PRESET +":}}") + @Deprecated private String encoderPreset = ""; /** * Encoder profile in adaptive bitrate, * It's baseline by default. + * @deprecated use {@link #encoderParameters} */ @Value( "${encoderProfile:${" + SETTINGS_ENCODING_PROFILE +":}}") + @Deprecated private String encoderProfile = ""; /** * Encoder level in adaptive bitrate + * @deprecated use {@link #encoderParameters} */ + @Deprecated @Value( "${encoderLevel:${" + SETTINGS_ENCODING_LEVEL +":}}") private String encoderLevel = ""; /** * Encoding rate control in adaptive bitrate + * @deprecated use {@link #encoderParameters} */ + @Deprecated @Value( "${encoderRc:${" + SETTINGS_ENCODING_RC +":}}") private String encoderRc = ""; @@ -1389,7 +1419,10 @@ public class AppSettings implements Serializable{ * This is the x264-params in ffmpeg * Specific settings for selected encoder, * For libx264 please check https://trac.ffmpeg.org/wiki/Encode/H.264 + * + * @deprecated use {@link #encoderParameters} */ + @Deprecated @Value( "${encoderSpecific:${" + SETTINGS_ENCODING_SPECIFIC +":}}") private String encoderSpecific = ""; @@ -1410,8 +1443,10 @@ public class AppSettings implements Serializable{ /** * Set quality/speed ratio modifier, Higher values speed up the encode at the cost of quality. + * @deprecated use {@link #encoderParameters} */ @Value( "${vp8EncoderSpeed:${" + SETTINGS_ENCODING_VP8_SPEED +":4}}") + @Deprecated private int vp8EncoderSpeed = 4; /** @@ -1419,8 +1454,11 @@ public class AppSettings implements Serializable{ * best * good * realtime + * + * @deprecated use {@link #encoderParameters} */ @Value( "${vp8EncoderDeadline:${" + SETTINGS_ENCODING_VP8_DEADLINE +":realtime}}") + @Deprecated private String vp8EncoderDeadline = "realtime"; /** @@ -1720,15 +1758,34 @@ public class AppSettings implements Serializable{ @Value("${dataChannelWebHookURL:${" + SETTINGS_DATA_CHANNEL_WEBHOOK_URL+":}}") private String dataChannelWebHookURL = ""; - + /** + * @deprecated. Please use {@link #encoderParameters} + */ + @Deprecated private String h265EncoderPreset; - + + /** + * @deprecated. Please use {@link #encoderParameters} + */ + @Deprecated private String h265EncoderProfile; + /** + * @deprecated. Please use {@link #encoderParameters} + */ + @Deprecated private String h265EncoderRc; + /** + * @deprecated. Please use {@link #encoderParameters} + */ + @Deprecated private String h265EncoderSpecific; + /** + * @deprecated. Please use {@link #encoderParameters} + */ + @Deprecated private String h265EncoderLevel; /** @@ -1781,9 +1838,10 @@ public class AppSettings implements Serializable{ /** * Constant Rate Factor used by x264, x265, VP8, * Use values between 4-51 - * + * @deprecated. Please use {@link #encoderParameters} */ @Value("${constantRateFactor:${"+SETTINGS_CONSTANT_RATE_FACTOR+":23}}") + @Deprecated private String constantRateFactor = "23"; /** @@ -2736,7 +2794,7 @@ public void setPlayTokenControlEnabled(boolean playTokenControlEnabled) { } /** - * @Deprecated Please use {@link #isEnableTimeTokenForPlay()} or {@link #isEnableTimeTokenForPublish()} + * @deprecated Please use {@link #isEnableTimeTokenForPlay()} or {@link #isEnableTimeTokenForPublish()} * @return */ @Deprecated @@ -3997,14 +4055,6 @@ public void setHlsSegmentType(String hlsSegmentType) { this.hlsSegmentType = hlsSegmentType; } - public String getHlsSegmentFileSuffixFormat() { - return hlsSegmentFileSuffixFormat; - } - - public void setHlsSegmentFileNameFormat(String hlsSegmentFileSuffixFormat) { - this.hlsSegmentFileSuffixFormat = hlsSegmentFileSuffixFormat; - } - public String getRecordingSubfolder() { return recordingSubfolder; } @@ -4179,4 +4229,32 @@ public int getS3TransferBufferSizeInBytes() { public void setS3TransferBufferSizeInBytes(int s3TransferBufferSizeInBytes) { this.s3TransferBufferSizeInBytes = s3TransferBufferSizeInBytes; } + + /** + * @return the encoderParameters + */ + public Map> getEncoderParameters() { + return encoderParameters; + } + + /** + * @param encoderParameters the encoderParameters to set + */ + public void setEncoderParameters(Map> encoderParameters) { + this.encoderParameters = encoderParameters; + } + + /** + * @return the hlsSegmentFileSuffixFormat + */ + public String getHlsSegmentFileSuffixFormat() { + return hlsSegmentFileSuffixFormat; + } + + /** + * @param hlsSegmentFileSuffixFormat the hlsSegmentFileSuffixFormat to set + */ + public void setHlsSegmentFileSuffixFormat(String hlsSegmentFileSuffixFormat) { + this.hlsSegmentFileSuffixFormat = hlsSegmentFileSuffixFormat; + } } diff --git a/src/main/java/io/antmedia/plugin/api/IStreamListener.java b/src/main/java/io/antmedia/plugin/api/IStreamListener.java index 4fb3bd463..d6fa3ceb3 100644 --- a/src/main/java/io/antmedia/plugin/api/IStreamListener.java +++ b/src/main/java/io/antmedia/plugin/api/IStreamListener.java @@ -10,10 +10,12 @@ public interface IStreamListener { * AMS inform the plugins when a stream is started with this method. * @param streamId is the id of the stream * - * @Deprecated use {@link #streamStarted(Broadcast)} because Broadcast object may be deleted when this method is called + * @deprecated use {@link #streamStarted(Broadcast)} because Broadcast object may be deleted when this method is called */ @Deprecated (since="3.0", forRemoval = true) - public void streamStarted(String streamId); + public default void streamStarted(String streamId) { + //do nothing + } /** * AMS inform the plugins when a stream is started with this method. @@ -28,10 +30,12 @@ public default void streamStarted(Broadcast broadcast) { * AMS inform the plugins when a stream is finished with this method. * @param streamId is the id of the stream * - * @Deprecated use {@link #streamFinished(Broadcast)} because Broadcast object may be deleted when this method is called + * @deprecated use {@link #streamFinished(Broadcast)} because Broadcast object may be deleted when this method is called */ @Deprecated (since="3.0", forRemoval = true) - public void streamFinished(String streamId); + public default void streamFinished(String streamId) { + //do nothing + } /** * AMS inform the plugins when a stream is finished with this method. diff --git a/src/test/java/io/antmedia/integration/MuxingTest.java b/src/test/java/io/antmedia/integration/MuxingTest.java index 2cf751fad..853381eec 100644 --- a/src/test/java/io/antmedia/integration/MuxingTest.java +++ b/src/test/java/io/antmedia/integration/MuxingTest.java @@ -833,7 +833,7 @@ public void testHLSSegmentFileName() { boolean hlsEnabled = appSettings.isHlsMuxingEnabled(); appSettings.setHlsMuxingEnabled(true); String hlsSegmentFileNameFormat = appSettings.getHlsSegmentFileSuffixFormat(); - appSettings.setHlsSegmentFileNameFormat("-%Y%m%d-%s"); + appSettings.setHlsSegmentFileSuffixFormat("-%Y%m%d-%s"); result = ConsoleAppRestServiceTest.callSetAppSettings("LiveApp", appSettings); assertTrue(result.isSuccess()); @@ -887,7 +887,7 @@ public void testHLSSegmentFileName() { }); appSettings.setHlsMuxingEnabled(hlsEnabled); - appSettings.setHlsSegmentFileNameFormat(hlsSegmentFileNameFormat); + appSettings.setHlsSegmentFileSuffixFormat(hlsSegmentFileNameFormat); ConsoleAppRestServiceTest.callSetAppSettings("LiveApp", appSettings); } catch (Exception e) { e.printStackTrace(); diff --git a/src/test/java/io/antmedia/test/AppSettingsUnitTest.java b/src/test/java/io/antmedia/test/AppSettingsUnitTest.java index 1f7dd9a0c..1c8753728 100644 --- a/src/test/java/io/antmedia/test/AppSettingsUnitTest.java +++ b/src/test/java/io/antmedia/test/AppSettingsUnitTest.java @@ -648,7 +648,7 @@ public void testUnsetAppSettings(AppSettings appSettings) { assertFalse(appSettings.isWriteSubscriberEventsToDatastore()); assertEquals("%09d", appSettings.getHlsSegmentFileSuffixFormat()); - appSettings.setHlsSegmentFileNameFormat("%s"); + appSettings.setHlsSegmentFileSuffixFormat("%s"); assertEquals("%s", appSettings.getHlsSegmentFileSuffixFormat()); @@ -662,13 +662,30 @@ public void testUnsetAppSettings(AppSettings appSettings) { assertEquals(10000000, appSettings.getS3TransferBufferSizeInBytes()); appSettings.setS3TransferBufferSizeInBytes(50000); assertEquals(50000, appSettings.getS3TransferBufferSizeInBytes()); + + Map> mapEncoderParameters = appSettings.getEncoderParameters(); + assertNotNull(mapEncoderParameters); + assertEquals(0, mapEncoderParameters.size()); + + Map libopenH264 = new HashMap<>(); + libopenH264.put("rc_mode", "quality"); + mapEncoderParameters.put("libopenh264", libopenH264); + + + appSettings.setEncoderParameters(mapEncoderParameters); + + mapEncoderParameters = appSettings.getEncoderParameters(); + assertNotNull(mapEncoderParameters); + assertEquals(1, mapEncoderParameters.size()); + assertEquals("quality", mapEncoderParameters.get("libopenh264").get("rc_mode")); + //if we add a new field, we just need to check its default value in this test //When a new field is added or removed please update the number of fields and make this test pass //by also checking its default value. assertEquals("New field is added to settings. PAY ATTENTION: Please CHECK ITS DEFAULT VALUE and fix the number of fields.", - 198, numberOfFields); + 199, numberOfFields); } diff --git a/src/test/java/io/antmedia/test/MuxerUnitTest.java b/src/test/java/io/antmedia/test/MuxerUnitTest.java index 002553f8e..51e443810 100644 --- a/src/test/java/io/antmedia/test/MuxerUnitTest.java +++ b/src/test/java/io/antmedia/test/MuxerUnitTest.java @@ -4006,7 +4006,7 @@ public void testHLSNaming() { hlsMuxer.init(appScope, "test", 300, "", 400000); assertEquals("./webapps/junit/streams/test_300p400kbps%09d.ts", hlsMuxer.getSegmentFilename()); - getAppSettings().setHlsSegmentFileNameFormat("-%Y%m%d-%s"); + getAppSettings().setHlsSegmentFileSuffixFormat("-%Y%m%d-%s"); hlsMuxer = new HLSMuxer(vertx, Mockito.mock(StorageClient.class), "", 7, null, false); hlsMuxer.init(appScope, "test", 0, "", 0); assertEquals("./webapps/junit/streams/test-%Y%m%d-%s.ts", hlsMuxer.getSegmentFilename()); diff --git a/src/test/java/io/antmedia/test/StreamFetcherUnitTest.java b/src/test/java/io/antmedia/test/StreamFetcherUnitTest.java index 37ba9e3b7..26c0c14a3 100644 --- a/src/test/java/io/antmedia/test/StreamFetcherUnitTest.java +++ b/src/test/java/io/antmedia/test/StreamFetcherUnitTest.java @@ -973,7 +973,9 @@ public void testHLSSourceFmp4() { String[] filesInStreams = new File("webapps/junit/streams").list(); boolean initFileFound = false; - String regex = streamId + "_" + System.currentTimeMillis()/100000 + "\\d{5}_init.mp4"; + + //matches 13 digits because System.currentTimeMillis() is used in the file + String regex = streamId + "_\\d{13}_init.mp4"; System.out.println("regex:"+regex); for (int i = 0; i < filesInStreams.length; i++) {