Skip to content

Commit bf95461

Browse files
authored
Merge branch 'master' into SrtRestream
2 parents df7ca05 + 38f23c3 commit bf95461

File tree

8 files changed

+162
-100
lines changed

8 files changed

+162
-100
lines changed

src/main/java/io/antmedia/datastore/db/DataStore.java

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,37 +1227,38 @@ protected void updateStreamInfo(Broadcast broadcast, BroadcastUpdate newBroadcas
12271227
* They are used by InMemoryDataStore and MapDBStore, Mongodb implements the same functionality inside its own class.
12281228
*/
12291229
protected ArrayList<VoD> searchOnServerVod(ArrayList<VoD> broadcastList, String search){
1230-
1230+
12311231
long startTime = System.nanoTime();
12321232
if(search != null && !search.isEmpty()) {
1233+
String searchLower = search.toLowerCase();
12331234
for (Iterator<VoD> i = broadcastList.iterator(); i.hasNext(); ) {
12341235
VoD item = i.next();
1235-
if(item.getVodName() != null && item.getStreamName() != null && item.getStreamId() != null && item.getVodId() != null) {
1236-
if (item.getVodName().toLowerCase().contains(search.toLowerCase()) || item.getStreamId().toLowerCase().contains(search.toLowerCase()) || item.getStreamName().toLowerCase().contains(search.toLowerCase()) || item.getVodId().toLowerCase().contains(search.toLowerCase()))
1237-
continue;
1238-
else i.remove();
1239-
}
1240-
else if (item.getVodName()!= null && item.getVodId() != null){
1241-
if (item.getVodName().toLowerCase().contains(search.toLowerCase()) || item.getVodId().toLowerCase().contains(search.toLowerCase()))
1242-
continue;
1243-
else i.remove();
1244-
}
1245-
else{
1246-
if (item.getVodId() != null){
1247-
if (item.getVodId().toLowerCase().contains(search.toLowerCase()))
1248-
continue;
1249-
else i.remove();
1250-
}
1236+
if (matchesVodSearch(item, searchLower)) {
1237+
continue;
12511238
}
1239+
i.remove();
12521240
}
12531241
}
1254-
1242+
12551243
long elapsedNanos = System.nanoTime() - startTime;
12561244
addQueryTime(elapsedNanos);
12571245
showWarningIfElapsedTimeIsMoreThanThreshold(elapsedNanos, "searchOnServerVod");
12581246
return broadcastList;
12591247
}
12601248

1249+
private boolean matchesVodSearch(VoD item, String searchLower) {
1250+
return containsIgnoreCase(item.getVodId(), searchLower) ||
1251+
containsIgnoreCase(item.getVodName(), searchLower) ||
1252+
containsIgnoreCase(item.getStreamId(), searchLower) ||
1253+
containsIgnoreCase(item.getStreamName(), searchLower) ||
1254+
containsIgnoreCase(item.getDescription(), searchLower) ||
1255+
containsIgnoreCase(item.getMetadata(), searchLower);
1256+
}
1257+
1258+
private boolean containsIgnoreCase(String field, String searchLower) {
1259+
return field != null && field.toLowerCase().contains(searchLower);
1260+
}
1261+
12611262
protected List<VoD> sortAndCropVodList(List<VoD> vodList, int offset, int size, String sortBy, String orderBy)
12621263
{
12631264
long startTime = System.nanoTime();

src/main/java/io/antmedia/datastore/db/MongoStore.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,9 @@ public List<VoD> getVodList(int offset, int size, String sortBy, String orderBy,
825825
Filters.regex(STREAM_ID).caseInsensitive().pattern(".*" + search + ".*"),
826826
Filters.regex("streamName").caseInsensitive().pattern(".*" + search + ".*"),
827827
Filters.regex(VOD_ID).caseInsensitive().pattern(".*" + search + ".*"),
828-
Filters.regex("vodName").caseInsensitive().pattern(".*" + search + ".*")
828+
Filters.regex("vodName").caseInsensitive().pattern(".*" + search + ".*"),
829+
Filters.regex("description").caseInsensitive().pattern(".*" + search + ".*"),
830+
Filters.regex("metadata").caseInsensitive().pattern(".*" + search + ".*")
829831
)
830832
);
831833

@@ -973,14 +975,16 @@ public long getPartialVodNumber(String search)
973975
synchronized(vodLock) {
974976

975977
Query<VoD> query = vodDatastore.find(VoD.class);
976-
if (search != null && !search.isEmpty())
978+
if (search != null && !search.isEmpty())
977979
{
978980
logger.info("Server side search is called for {}", search);
979981
query.filter(Filters.or(
980982
Filters.regex("streamId").caseInsensitive().pattern(".*" + search + ".*"),
981983
Filters.regex("streamName").caseInsensitive().pattern(".*" + search + ".*"),
982984
Filters.regex(VOD_ID).caseInsensitive().pattern(".*" + search + ".*"),
983-
Filters.regex("vodName").caseInsensitive().pattern(".*" + search + ".*")
985+
Filters.regex("vodName").caseInsensitive().pattern(".*" + search + ".*"),
986+
Filters.regex("description").caseInsensitive().pattern(".*" + search + ".*"),
987+
Filters.regex("metadata").caseInsensitive().pattern(".*" + search + ".*")
984988
));
985989
}
986990
partialVodNumber = query.count();

src/main/java/io/antmedia/rest/RestServiceBase.java

Lines changed: 52 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,98 +1252,76 @@ protected String getStreamsDirectory(String appScopeName) {
12521252
return String.format("%s/webapps/%s/%s", System.getProperty("red5.root"), appScopeName, "streams");
12531253
}
12541254

1255-
protected Result uploadVoDFile(String fileName, InputStream inputStream) {
1256-
boolean success = false;
1257-
String message = "";
1258-
String id= null;
1255+
public Result uploadVoDFile(String fileName, InputStream inputStream) {
1256+
return uploadVoDFile(fileName, inputStream, null);
1257+
}
1258+
1259+
public Result uploadVoDFile(String fileName, InputStream inputStream, String metadata) {
1260+
String id = null;
12591261
String appScopeName = getScope().getName();
12601262
String fileExtension = FilenameUtils.getExtension(fileName);
1261-
try {
1262-
1263-
String[] supportedFormats = new String[] {"mp4", "webm", "mov", "avi", "mp3", "wmv"};
1264-
1265-
if (ArrayUtils.contains(supportedFormats, fileExtension)) {
1266-
1267-
1268-
IStatsCollector statsCollector = (IStatsCollector) getAppContext().getBean(IStatsCollector.BEAN_NAME);
1269-
String vodUploadFinishScript = getAppSettings().getVodUploadFinishScript();
1270-
if (StringUtils.isNotBlank(vodUploadFinishScript) && !statsCollector.enoughResource())
1271-
{
1272-
logger.info("Not enough resource to upload VoD file");
1273-
message = "Not enough system resources available to upload and process VoD File";
1274-
}
1275-
else
1276-
{
1277-
1278-
File streamsDirectory = new File(
1279-
getStreamsDirectory(appScopeName));
1280-
1281-
// if the directory does not exist, create it
1282-
if (!streamsDirectory.exists()) {
1283-
streamsDirectory.mkdirs();
1284-
}
1285-
String vodId = RandomStringUtils.secure().nextNumeric(24);
1286-
1287-
1288-
File savedFile = new File(streamsDirectory, vodId + "." + fileExtension);
1289-
1290-
if (!savedFile.toPath().normalize().startsWith(streamsDirectory.toPath().normalize())) {
1291-
throw new IOException("Entry is outside of the target directory");
1292-
}
1293-
1294-
int read = 0;
1295-
byte[] bytes = new byte[2048];
1296-
try (OutputStream outpuStream = new FileOutputStream(savedFile))
1297-
{
1298-
1299-
while ((read = inputStream.read(bytes)) != -1) {
1300-
outpuStream.write(bytes, 0, read);
1301-
}
1302-
outpuStream.flush();
1263+
1264+
String[] supportedFormats = new String[] {"mp4", "webm", "mov", "avi", "mp3", "wmv"};
1265+
if (!ArrayUtils.contains(supportedFormats, fileExtension)) {
1266+
//this message has been used in the frontend(webpanel) pay attention
1267+
return new Result(false, null, "notSupportedFileType");
1268+
}
13031269

1304-
long fileSize = savedFile.length();
1305-
long unixTime = System.currentTimeMillis();
1270+
IStatsCollector statsCollector = (IStatsCollector) getAppContext().getBean(IStatsCollector.BEAN_NAME);
1271+
String vodUploadFinishScript = getAppSettings().getVodUploadFinishScript();
1272+
if (StringUtils.isNotBlank(vodUploadFinishScript) && !statsCollector.enoughResource()) {
1273+
logger.info("Not enough resource to upload VoD file");
1274+
return new Result(false, null, "Not enough system resources available to upload and process VoD File");
1275+
}
13061276

1307-
String path = savedFile.getPath();
1277+
try {
1278+
File streamsDirectory = new File(getStreamsDirectory(appScopeName));
1279+
if (!streamsDirectory.exists()) {
1280+
streamsDirectory.mkdirs();
1281+
}
13081282

1283+
String vodId = RandomStringUtils.secure().nextNumeric(24);
1284+
File savedFile = new File(streamsDirectory, vodId + "." + fileExtension);
13091285

1310-
String relativePath = AntMediaApplicationAdapter.getRelativePath(path);
1286+
if (!savedFile.toPath().normalize().startsWith(streamsDirectory.toPath().normalize())) {
1287+
throw new IOException("Entry is outside of the target directory");
1288+
}
13111289

1312-
VoD newVod = new VoD(fileName, "file", relativePath, fileName, unixTime, 0, Muxer.getDurationInMs(savedFile,fileName), fileSize,
1313-
VoD.UPLOADED_VOD, vodId, null);
1290+
int read = 0;
1291+
byte[] bytes = new byte[2048];
1292+
try (OutputStream outpuStream = new FileOutputStream(savedFile)) {
1293+
while ((read = inputStream.read(bytes)) != -1) {
1294+
outpuStream.write(bytes, 0, read);
1295+
}
1296+
outpuStream.flush();
13141297

1315-
if (StringUtils.isNotBlank(vodUploadFinishScript)) {
1316-
newVod.setProcessStatus(VoD.PROCESS_STATUS_INQUEUE);
1317-
}
1298+
long fileSize = savedFile.length();
1299+
long unixTime = System.currentTimeMillis();
1300+
String relativePath = AntMediaApplicationAdapter.getRelativePath(savedFile.getPath());
13181301

1319-
id = getDataStore().addVod(newVod);
1302+
VoD newVod = new VoD(fileName, "file", relativePath, fileName, unixTime, 0,
1303+
Muxer.getDurationInMs(savedFile, fileName), fileSize, VoD.UPLOADED_VOD, vodId, null);
13201304

1321-
if(id != null) {
1322-
success = true;
1323-
message = id;
1305+
if (StringUtils.isNotBlank(metadata)) {
1306+
newVod.setMetadata(metadata);
1307+
}
13241308

1325-
if (StringUtils.isNotBlank(vodUploadFinishScript))
1326-
{
1327-
startVoDScriptProcess(vodUploadFinishScript, savedFile, newVod, id);
1309+
if (StringUtils.isNotBlank(vodUploadFinishScript)) {
1310+
newVod.setProcessStatus(VoD.PROCESS_STATUS_INQUEUE);
1311+
}
13281312

1329-
}
1313+
id = getDataStore().addVod(newVod);
13301314

1331-
}
1332-
}
1315+
if (id != null && StringUtils.isNotBlank(vodUploadFinishScript)) {
1316+
startVoDScriptProcess(vodUploadFinishScript, savedFile, newVod, id);
13331317
}
13341318
}
1335-
else {
1336-
//this message has been used in the frontend(webpanel) pay attention
1337-
message = "notSupportedFileType";
1338-
}
1339-
1340-
}
1341-
catch (IOException iox) {
1319+
} catch (IOException iox) {
13421320
logger.error(iox.getMessage());
1321+
return new Result(false, null, "");
13431322
}
13441323

1345-
1346-
return new Result(success, id, message);
1324+
return new Result(id != null, id, id != null ? id : "");
13471325
}
13481326

13491327
public void startVoDScriptProcess(String vodUploadFinishScript, File savedFile, VoD newVod, String vodId) {

src/main/java/io/antmedia/rest/VoDRestService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,9 @@ public Result deleteVoDsBulk(
171171
@Override
172172
public Result uploadVoDFile(
173173
@Parameter(description = "Name of the VoD File", required = true) @QueryParam("name") String fileName,
174-
@Parameter(description = "VoD file", required = true) @FormDataParam("file") InputStream inputStream) {
175-
return super.uploadVoDFile(fileName, inputStream);
174+
@Parameter(description = "VoD file", required = true) @FormDataParam("file") InputStream inputStream,
175+
@Parameter(description = "Custom metadata for the VoD file", required = false) @FormDataParam("metadata") String metadata) {
176+
return super.uploadVoDFile(fileName, inputStream, metadata);
176177
}
177178

178179

src/main/java/io/antmedia/streamsource/StreamFetcherManager.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -567,8 +567,7 @@ public void controlStreamFetchers(boolean restart) {
567567
//stream blocked means there is a connection to stream source and it's waiting to read a new packet
568568
//Most of the time the problem is related to the stream source side.
569569

570-
if (!streamScheduler.isStreamBlocked() && !streamScheduler.isStreamAlive() &&
571-
broadcast != null && AntMediaApplicationAdapter.BROADCAST_STATUS_TERMINATED_UNEXPECTEDLY.equals(broadcast.getStatus())) {
570+
if (!streamScheduler.isStreamBlocked() && !streamScheduler.isStreamAlive() && AntMediaApplicationAdapter.BROADCAST_STATUS_TERMINATED_UNEXPECTEDLY.equals(broadcast.getStatus())) {
572571
// if it's not blocked and it's not alive, stop the stream
573572
logger.info("Stopping the stream because it is not getting updated(aka terminated_unexpectedly) and it will start for the streamId:{}", streamScheduler.getStreamId());
574573
stopStreaming(streamScheduler.getStreamId(), false);

src/test/java/io/antmedia/integration/RestServiceV2Test.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,10 @@ public static String callAddStreamSource(Broadcast broadcast, boolean autoStart)
568568

569569

570570
public static Result callUploadVod(File file) throws Exception {
571+
return callUploadVod(file, null);
572+
}
573+
574+
public static Result callUploadVod(File file, String metadata) throws Exception {
571575

572576
String url = ROOT_SERVICE_URL + "/v2/vods/create?name=" + file.getName();
573577
HttpClient client = HttpClients.custom().setRedirectStrategy(new LaxRedirectStrategy()).build();
@@ -580,6 +584,10 @@ public static Result callUploadVod(File file) throws Exception {
580584

581585
builder.addPart("file", fileBody);
582586

587+
if (metadata != null) {
588+
builder.addTextBody("metadata", metadata);
589+
}
590+
583591
HttpEntity entity = builder.build();
584592
post.setEntity(entity);
585593
HttpResponse response = client.execute(post);
@@ -1161,7 +1169,21 @@ public void testUploadVoDFile() {
11611169
//file should be deleted
11621170
assertFalse(MuxingTest.isURLAvailable("http://" + SERVER_ADDR + ":5080/LiveApp/streams/" + vodId + ".mp4"));
11631171

1172+
// Test upload with metadata
1173+
String testMetadata = "{\"customField\":\"testValue\"}";
1174+
try {
1175+
result = callUploadVod(file, testMetadata);
1176+
} catch (Exception e) {
1177+
e.printStackTrace();
1178+
}
1179+
assertTrue(result.isSuccess());
1180+
String vodIdWithMetadata = result.getMessage();
1181+
1182+
VoD vodWithMetadata = callGetVoD(vodIdWithMetadata);
1183+
assertNotNull(vodWithMetadata);
1184+
assertEquals(testMetadata, vodWithMetadata.getMetadata());
11641185

1186+
deleteVoD(vodIdWithMetadata);
11651187

11661188
}
11671189

src/test/java/io/antmedia/test/db/DBStoresUnitTest.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,45 @@ private void testVodSearch(DataStore dataStore){
21462146
vodList = dataStore.getVodList(0, 50, null, null, null, "vassdfsdgs");
21472147
assertEquals(0, vodList.size());
21482148

2149+
// Test search by metadata
2150+
VoD vodWithMetadata = new VoD("metaStream", "meta123" + (int)(Math.random() * 1000), "path", "metaVodName", 1517239908, 123, 17933, 1190425, VoD.STREAM_VOD, "metaVodId" + (int)(Math.random() * 91000), null);
2151+
vodWithMetadata.setMetadata("team=A,event=championship");
2152+
dataStore.addVod(vodWithMetadata);
2153+
2154+
vodList = dataStore.getVodList(0, 50, null, null, null, "team=A");
2155+
assertEquals(1, vodList.size());
2156+
assertEquals(vodWithMetadata.getVodId(), vodList.get(0).getVodId());
2157+
2158+
vodList = dataStore.getVodList(0, 50, null, null, null, "championship");
2159+
assertEquals(1, vodList.size());
2160+
assertEquals(vodWithMetadata.getVodId(), vodList.get(0).getVodId());
2161+
2162+
partialVodNumber = dataStore.getPartialVodNumber("team=A");
2163+
assertEquals(1, partialVodNumber);
2164+
2165+
// Test search by description
2166+
VoD vodWithDescription = new VoD("descStream", "desc123" + (int)(Math.random() * 1000), "path", "descVodName", 1517239908, 123, 17933, 1190425, VoD.STREAM_VOD, "descVodId" + (int)(Math.random() * 91000), null);
2167+
vodWithDescription.setDescription("Important recorded segment from Event B");
2168+
dataStore.addVod(vodWithDescription);
2169+
2170+
vodList = dataStore.getVodList(0, 50, null, null, null, "Event B");
2171+
assertEquals(1, vodList.size());
2172+
assertEquals(vodWithDescription.getVodId(), vodList.get(0).getVodId());
2173+
2174+
vodList = dataStore.getVodList(0, 50, null, null, null, "recorded segment");
2175+
assertEquals(1, vodList.size());
2176+
assertEquals(vodWithDescription.getVodId(), vodList.get(0).getVodId());
2177+
2178+
partialVodNumber = dataStore.getPartialVodNumber("Event B");
2179+
assertEquals(1, partialVodNumber);
2180+
2181+
// Test case insensitive search for metadata and description
2182+
vodList = dataStore.getVodList(0, 50, null, null, null, "TEAM=A");
2183+
assertEquals(1, vodList.size());
2184+
2185+
vodList = dataStore.getVodList(0, 50, null, null, null, "event b");
2186+
assertEquals(1, vodList.size());
2187+
21492188
}
21502189

21512190

src/test/java/io/antmedia/test/rest/VoDRestServiceV2UnitTest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,26 @@ public void testUploadVodFile() throws FileNotFoundException, IOException {
366366
assertEquals(3, store.getTotalVodNumber());
367367

368368
assertEquals(3, restServiceReal.getTotalVodNumber().getNumber());
369+
370+
// Test upload with metadata
371+
try (FileInputStream inputStream4 = new FileInputStream("src/test/resources/sample_MP4_480.mp4")) {
372+
String testMetadata = "{\"customField\":\"value\"}";
373+
Result result4 = restServiceReal.uploadVoDFile(fileName, inputStream4, testMetadata);
374+
assertTrue(result4.isSuccess());
375+
376+
VoD vodWithMetadata = restServiceReal.getVoD(result4.getDataId());
377+
assertEquals(testMetadata, vodWithMetadata.getMetadata());
378+
}
379+
380+
// Test upload without metadata (null) - should work, metadata should be null
381+
try (FileInputStream inputStream5 = new FileInputStream("src/test/resources/sample_MP4_480.mp4")) {
382+
Result result5 = restServiceReal.uploadVoDFile(fileName, inputStream5, null);
383+
assertTrue(result5.isSuccess());
384+
385+
VoD vodWithoutMetadata = restServiceReal.getVoD(result5.getDataId());
386+
assertNull(vodWithoutMetadata.getMetadata());
387+
}
369388
}
370-
371389

372390

373391
}

0 commit comments

Comments
 (0)