Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it easy to configure encoders #6912

Merged
merged 5 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 97 additions & 19 deletions src/main/java/io/antmedia/AppSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = "";

/**
Expand Down Expand Up @@ -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<String, Map<String,String>> 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 = "";

Expand All @@ -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 = "";

Expand All @@ -1410,17 +1443,22 @@ 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;

/**
* VP8 Encoder deadline:
* best
* good
* realtime
*
* @deprecated use {@link #encoderParameters}
*/
@Value( "${vp8EncoderDeadline:${" + SETTINGS_ENCODING_VP8_DEADLINE +":realtime}}")
@Deprecated
private String vp8EncoderDeadline = "realtime";

/**
Expand Down Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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";

/**
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -4179,4 +4229,32 @@ public int getS3TransferBufferSizeInBytes() {
public void setS3TransferBufferSizeInBytes(int s3TransferBufferSizeInBytes) {
this.s3TransferBufferSizeInBytes = s3TransferBufferSizeInBytes;
}

/**
* @return the encoderParameters
*/
public Map<String, Map<String,String>> getEncoderParameters() {
return encoderParameters;
}

/**
* @param encoderParameters the encoderParameters to set
*/
public void setEncoderParameters(Map<String, Map<String,String>> 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;
}
}
12 changes: 8 additions & 4 deletions src/main/java/io/antmedia/plugin/api/IStreamListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/io/antmedia/integration/MuxingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down Expand Up @@ -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();
Expand Down
21 changes: 19 additions & 2 deletions src/test/java/io/antmedia/test/AppSettingsUnitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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());


Expand All @@ -662,13 +662,30 @@ public void testUnsetAppSettings(AppSettings appSettings) {
assertEquals(10000000, appSettings.getS3TransferBufferSizeInBytes());
appSettings.setS3TransferBufferSizeInBytes(50000);
assertEquals(50000, appSettings.getS3TransferBufferSizeInBytes());

Map<String, Map<String, String>> mapEncoderParameters = appSettings.getEncoderParameters();
assertNotNull(mapEncoderParameters);
assertEquals(0, mapEncoderParameters.size());

Map<String, String> 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);
}


Expand Down
2 changes: 1 addition & 1 deletion src/test/java/io/antmedia/test/MuxerUnitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
4 changes: 3 additions & 1 deletion src/test/java/io/antmedia/test/StreamFetcherUnitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down
Loading