diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/RecordingProperties.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/RecordingProperties.java index 624926dc..37752e90 100644 --- a/openvidu-java-client/src/main/java/io/openvidu/java/client/RecordingProperties.java +++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/RecordingProperties.java @@ -716,8 +716,7 @@ public class RecordingProperties { * @hidden */ public final static Map removeNonBroadcastProperties(Map params) { - List nonBroadcastProps = Arrays - .asList(new String[] { "outputMode", "name", "hasVideo", "ignoreFailedStreams" }); + List nonBroadcastProps = Arrays.asList(new String[] { "outputMode", "name", "ignoreFailedStreams" }); nonBroadcastProps.forEach(p -> params.remove(p)); return params; } diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduProTestAppE2eTest.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduProTestAppE2eTest.java index f735e0c5..28d3496e 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduProTestAppE2eTest.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduProTestAppE2eTest.java @@ -2867,6 +2867,67 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest { } } + @Test + @DisplayName("Successfull only video only audio broadcast Test") + void sucessfullBroadcastOnlyVideoOnlyAudioTest() throws Exception { + + log.info("Successfull only video only audio broadcast Test"); + + try { + String BROADCAST_IP = TestUtils.startRtmpServer(); + + OpenViduTestappUser user = setupBrowserAndConnectToOpenViduTestapp("chrome"); + user.getDriver().findElement(By.id("add-user-btn")).click(); + user.getDriver().findElement(By.className("join-btn")).sendKeys(Keys.ENTER); + user.getEventManager().waitUntilEventReaches("streamCreated", 1); + user.getEventManager().waitUntilEventReaches("streamPlaying", 1); + + user.getDriver().findElement(By.id("session-api-btn-0")).click(); + Thread.sleep(750); + WebElement broadcastUrlField = user.getDriver().findElement(By.id("broadcasturl-id-field")); + broadcastUrlField.clear(); + broadcastUrlField.sendKeys("rtmp://" + BROADCAST_IP + "/live"); + user.getDriver().findElement(By.id("broadcast-properties-btn")).click(); + Thread.sleep(500); + + // Only video + user.getDriver().findElement(By.id("rec-hasaudio-checkbox")).click(); + Thread.sleep(500); + + user.getDriver().findElement(By.id("start-broadcast-btn")).click(); + user.getWaiter().until( + ExpectedConditions.attributeToBe(By.id("api-response-text-area"), "value", "Broadcast started")); + user.getEventManager().waitUntilEventReaches("broadcastStarted", 1); + + checkRtmpRecordingIsFine(30, RecordingUtils::checkVideoAverageRgbGreen); + + user.getDriver().findElement(By.id("stop-broadcast-btn")).click(); + user.getWaiter().until( + ExpectedConditions.attributeToBe(By.id("api-response-text-area"), "value", "Broadcast stopped")); + user.getEventManager().waitUntilEventReaches("broadcastStopped", 1); + + // Only audio + user.getDriver().findElement(By.id("rec-hasaudio-checkbox")).click(); + user.getDriver().findElement(By.id("rec-hasvideo-checkbox")).click(); + Thread.sleep(500); + + user.getDriver().findElement(By.id("start-broadcast-btn")).click(); + user.getWaiter().until( + ExpectedConditions.attributeToBe(By.id("api-response-text-area"), "value", "Broadcast started")); + user.getEventManager().waitUntilEventReaches("broadcastStarted", 1); + + user.getDriver().findElement(By.id("stop-broadcast-btn")).click(); + user.getWaiter().until( + ExpectedConditions.attributeToBe(By.id("api-response-text-area"), "value", "Broadcast stopped")); + user.getEventManager().waitUntilEventReaches("broadcastStopped", 1); + + gracefullyLeaveParticipants(user, 1); + + } finally { + TestUtils.stopRtmpServer(); + } + } + @Test @DisplayName("Wrong broadcast Test") void wrongBroadcastTest() throws Exception { @@ -2911,6 +2972,9 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest { // 422 body = "{'session':'TestSession','broadcastUrl':'rtmp://" + BROADCAST_IP + "/live','resolution':'99x1280'}"; restClient.rest(HttpMethod.POST, "/openvidu/api/broadcast/start", body, 422); + body = "{'session':'TestSession','broadcastUrl':'rtmp://" + BROADCAST_IP + + "/live','hasAudio':false,'hasVideo':false}"; + restClient.rest(HttpMethod.POST, "/openvidu/api/broadcast/start", body, 422); // 500 (Connection refused) body = "{'session':'TestSession','broadcastUrl':'rtmps://" + BROADCAST_IP + "/live'}"; String errorResponse = restClient.commonRestString(HttpMethod.POST, "/openvidu/api/broadcast/start", body, @@ -3003,7 +3067,7 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest { Map config = Map.of("OPENVIDU_PRO_SPEECH_TO_TEXT", "disabled", "OPENVIDU_RECORDING", true, "OPENVIDU_RECORDING_CUSTOM_LAYOUT", "/opt/openvidu/test-layouts"); restartOpenViduServer(config); - + final String SESSION_NAME = "CUSTOM_LAYOUT_SESSION"; OpenViduTestappUser user = setupBrowserAndConnectToOpenViduTestapp("chrome"); @@ -3085,7 +3149,16 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest { // Analyze most recent file (there can be more than one in the path) File[] files = new File(broadcastRecordingPath + "/tmp").listFiles(); Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed()); - commandLine.executeCommand("ffmpeg -i " + files[0].getAbsolutePath() + " -vframes 1 " + // This fixes corrupted video files + String fixedFile = broadcastRecordingPath + "/tmp/test.flv"; + commandLine.executeCommand( + "ffmpeg -i " + files[0].getAbsolutePath() + " -acodec copy -vcodec copy " + fixedFile, 10); + // This obtains the middle duration of the video + String videoDuration = commandLine.executeCommand( + "ffprobe -loglevel error -of csv=p=0 -show_entries format=duration " + fixedFile, 3); + float halfDuration = (float) (Float.parseFloat(videoDuration) * 0.5); + // This retrieves the frame from the middle of the video + commandLine.executeCommand("ffmpeg -ss " + halfDuration + " -i " + fixedFile + " -vframes 1 " + broadcastRecordingPath + "/tmp/rtmp-screenshot.jpg", 3); File screenshot = new File(broadcastRecordingPath + "/tmp/rtmp-screenshot.jpg"); if (screenshot.exists() && screenshot.isFile() && screenshot.length() > 0 && screenshot.canRead()) { diff --git a/openvidu-testapp/src/app/components/dialogs/recording-properties/recording-properties.component.html b/openvidu-testapp/src/app/components/dialogs/recording-properties/recording-properties.component.html index 35d6db45..34c7a533 100644 --- a/openvidu-testapp/src/app/components/dialogs/recording-properties/recording-properties.component.html +++ b/openvidu-testapp/src/app/components/dialogs/recording-properties/recording-properties.component.html @@ -17,8 +17,7 @@
Has audio - Has - video + Has video Ignore failed streams
diff --git a/openvidu-testapp/src/app/components/dialogs/recording-properties/recording-properties.component.ts b/openvidu-testapp/src/app/components/dialogs/recording-properties/recording-properties.component.ts index a95e5316..37941227 100644 --- a/openvidu-testapp/src/app/components/dialogs/recording-properties/recording-properties.component.ts +++ b/openvidu-testapp/src/app/components/dialogs/recording-properties/recording-properties.component.ts @@ -11,22 +11,12 @@ export class RecordingPropertiesComponent { @Input() isBroadcast = false; + @Input() + recordingProperties: RecordingProperties; + recMode = Recording.OutputMode; recLayouts = RecordingLayout; - getRecordingProperties: RecordingProperties; - @Output() recordingPropertiesChange: EventEmitter = new EventEmitter(); - - @Input() - get recordingProperties(): RecordingProperties { - return this.getRecordingProperties; - } - - set recordingProperties(value: RecordingProperties) { - this.getRecordingProperties = value; - this.recordingPropertiesChange.emit(this.getRecordingProperties); - } - enumToArray(enumerator: any) { return Object.keys(enumerator); } diff --git a/openvidu-testapp/src/app/components/dialogs/session-api-dialog/session-api-dialog.component.html b/openvidu-testapp/src/app/components/dialogs/session-api-dialog/session-api-dialog.component.html index b5efdda9..02cf206e 100644 --- a/openvidu-testapp/src/app/components/dialogs/session-api-dialog/session-api-dialog.component.html +++ b/openvidu-testapp/src/app/components/dialogs/session-api-dialog/session-api-dialog.component.html @@ -77,7 +77,8 @@ aria-label="Recording properties"> {{recPropertiesIcon}} - +
@@ -106,7 +107,8 @@ {{broadcastPropertiesIcon}} - +
@@ -120,6 +122,6 @@ + [mat-dialog-close]="{session: session, recordingProperties: recordingProperties, broadcastProperties: broadcastProperties}">CLOSE \ No newline at end of file diff --git a/openvidu-testapp/src/app/components/dialogs/session-api-dialog/session-api-dialog.component.ts b/openvidu-testapp/src/app/components/dialogs/session-api-dialog/session-api-dialog.component.ts index 13317ee1..3be62a42 100644 --- a/openvidu-testapp/src/app/components/dialogs/session-api-dialog/session-api-dialog.component.ts +++ b/openvidu-testapp/src/app/components/dialogs/session-api-dialog/session-api-dialog.component.ts @@ -248,11 +248,15 @@ export class SessionApiDialogComponent { toggleRecProperties() { this.showRecProperties = !this.showRecProperties; this.recPropertiesIcon = this.showRecProperties ? 'remove_circle' : 'add_circle'; + this.showBroadcastProperties = false; + this.broadcastPropertiesIcon = 'add_circle'; } toggleBroadcastProperties() { this.showBroadcastProperties = !this.showBroadcastProperties; this.broadcastPropertiesIcon = this.showBroadcastProperties ? 'remove_circle' : 'add_circle'; + this.showRecProperties = false; + this.recPropertiesIcon = 'add_circle'; } changedNumIceServers(numIceServers: number) { diff --git a/openvidu-testapp/src/app/components/dialogs/session-properties-dialog/session-properties-dialog.component.html b/openvidu-testapp/src/app/components/dialogs/session-properties-dialog/session-properties-dialog.component.html index 0d49f036..019039eb 100644 --- a/openvidu-testapp/src/app/components/dialogs/session-properties-dialog/session-properties-dialog.component.html +++ b/openvidu-testapp/src/app/components/dialogs/session-properties-dialog/session-properties-dialog.component.html @@ -20,7 +20,7 @@ - +
diff --git a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts index 406dcb6b..5c801c53 100644 --- a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts +++ b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts @@ -649,13 +649,15 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { } openSessionApiDialog() { + const defaultRecordingProperties = JSON.parse(JSON.stringify(this.sessionProperties.defaultRecordingProperties)); + const defaultBroadcastProperties = JSON.parse(JSON.stringify(this.sessionProperties.defaultRecordingProperties)); const dialogRef = this.dialog.open(SessionApiDialogComponent, { data: { openVidu: !!this.OV_NodeClient ? this.OV_NodeClient : new OpenViduAPI(this.openviduUrl, this.openviduSecret), session: this.sessionAPI, sessionId: !!this.session ? this.session.sessionId : this.sessionName, - recordingProperties: !!this.recordingProperties ? this.recordingProperties : this.sessionProperties.defaultRecordingProperties, - broadcastProperties: !!this.broadcastProperties ? this.broadcastProperties : this.sessionProperties.defaultRecordingProperties + recordingProperties: !!this.recordingProperties ? this.recordingProperties : defaultRecordingProperties, + broadcastProperties: !!this.broadcastProperties ? this.broadcastProperties : defaultBroadcastProperties }, disableClose: true }); @@ -665,6 +667,7 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { delete this.sessionAPI; } this.recordingProperties = result.recordingProperties; + this.broadcastProperties = result.broadcastProperties; document.getElementById('session-api-btn-' + this.index).classList.remove('cdk-program-focused'); }); }