mirror of https://github.com/OpenVidu/openvidu.git
Enable google cloud storage uploading for recordings
parent
bd3b0f5b66
commit
e3992b4383
|
@ -327,6 +327,18 @@
|
|||
<artifactId>openvidu-java-client</artifactId>
|
||||
<version>${version.openvidu.java.client}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.cloud</groupId>
|
||||
<artifactId>libraries-bom</artifactId>
|
||||
<version>16.1.0</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.cloud</groupId>
|
||||
<artifactId>google-cloud-storage</artifactId>
|
||||
<version>1.113.4</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Test dependencies -->
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import io.openvidu.server.recording.*;
|
||||
import org.bouncycastle.util.Arrays;
|
||||
import org.kurento.jsonrpc.internal.server.config.JsonRpcConfiguration;
|
||||
import org.kurento.jsonrpc.server.JsonRpcConfigurer;
|
||||
|
@ -61,10 +62,6 @@ import io.openvidu.server.kurento.kms.DummyLoadManager;
|
|||
import io.openvidu.server.kurento.kms.FixedOneKmsManager;
|
||||
import io.openvidu.server.kurento.kms.KmsManager;
|
||||
import io.openvidu.server.kurento.kms.LoadManager;
|
||||
import io.openvidu.server.recording.DummyRecordingDownloader;
|
||||
import io.openvidu.server.recording.DummyRecordingUploader;
|
||||
import io.openvidu.server.recording.RecordingDownloader;
|
||||
import io.openvidu.server.recording.RecordingUploader;
|
||||
import io.openvidu.server.recording.service.RecordingManager;
|
||||
import io.openvidu.server.recording.service.RecordingManagerUtils;
|
||||
import io.openvidu.server.recording.service.RecordingManagerUtilsLocalStorage;
|
||||
|
@ -203,7 +200,11 @@ public class OpenViduServer implements JsonRpcConfigurer {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public RecordingUploader recordingUpload() {
|
||||
@DependsOn("openviduConfig")
|
||||
public RecordingUploader recordingUpload(OpenviduConfig openviduConfig) {
|
||||
if (openviduConfig.isGcpRecordingStorageEnabled()) {
|
||||
return new GoogleCloudStorageRecordingUploader();
|
||||
}
|
||||
return new DummyRecordingUploader();
|
||||
}
|
||||
|
||||
|
|
|
@ -190,6 +190,10 @@ public class OpenviduConfig {
|
|||
|
||||
private String dotenvPath;
|
||||
|
||||
private boolean gcpRecordingStorageEnabled;
|
||||
|
||||
private String gcpStorageBucketName;
|
||||
|
||||
// Derived properties
|
||||
|
||||
public static String finalUrl;
|
||||
|
@ -338,6 +342,14 @@ public class OpenviduConfig {
|
|||
return dotenvPath;
|
||||
}
|
||||
|
||||
public boolean isGcpRecordingStorageEnabled() {
|
||||
return gcpRecordingStorageEnabled;
|
||||
}
|
||||
|
||||
public String getGcpStorageBucketName() {
|
||||
return gcpStorageBucketName;
|
||||
}
|
||||
|
||||
// Derived properties methods
|
||||
|
||||
public String getSpringProfile() {
|
||||
|
@ -533,6 +545,10 @@ public class OpenviduConfig {
|
|||
openviduForcedCodec = asEnumValue("OPENVIDU_STREAMS_FORCED_VIDEO_CODEC", VideoCodec.class);
|
||||
openviduAllowTranscoding = asBoolean("OPENVIDU_STREAMS_ALLOW_TRANSCODING");
|
||||
|
||||
gcpRecordingStorageEnabled = asBoolean("OPENVIDU_GCP_RECORDING_STORAGE_ENABLED");
|
||||
gcpStorageBucketName = gcpRecordingStorageEnabled ? asNonEmptyString("OPENVIDU_GCP_STORAGE_BUCKET_NAME")
|
||||
: null;
|
||||
|
||||
kmsUrisList = checkKmsUris();
|
||||
|
||||
checkCoturnIp();
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package io.openvidu.server.recording;
|
||||
|
||||
import com.google.cloud.storage.BlobId;
|
||||
import com.google.cloud.storage.BlobInfo;
|
||||
import com.google.cloud.storage.Storage;
|
||||
import com.google.cloud.storage.StorageException;
|
||||
import io.openvidu.server.config.OpenviduConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class GoogleCloudStorageRecordingUploader implements RecordingUploader {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(GoogleCloudStorageRecordingUploader.class);
|
||||
|
||||
@Autowired
|
||||
private OpenviduConfig config;
|
||||
|
||||
@Autowired
|
||||
private Storage gcpStorage;
|
||||
|
||||
private final Set<String> recordingsBeingCurrentlyUploaded = ConcurrentHashMap.newKeySet();
|
||||
|
||||
@Override
|
||||
public void uploadRecording(Recording recording, Runnable successCallback, Runnable errorCallback) {
|
||||
recordingsBeingCurrentlyUploaded.add(recording.getId());
|
||||
|
||||
String bucketName = config.getGcpStorageBucketName();
|
||||
BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of(bucketName, recording.getName())).build();
|
||||
String filePath = getComposedRecordingLocalFilePath(recording);
|
||||
|
||||
try {
|
||||
gcpStorage.create(blobInfo, Files.readAllBytes(Paths.get(filePath)));
|
||||
} catch (StorageException | IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
errorCallback.run();
|
||||
} finally {
|
||||
recordingsBeingCurrentlyUploaded.remove(recording.getId());
|
||||
}
|
||||
successCallback.run();
|
||||
}
|
||||
|
||||
private String getComposedRecordingLocalFilePath(Recording recording) {
|
||||
// Audio-only recordings are in WEBM file format
|
||||
String fileExt = recording.hasVideo() ? ".mp4" : ".webm";
|
||||
return config.getOpenViduRecordingPath() + "/" + recording.getId() + "/" + recording.getName() + fileExt;
|
||||
}
|
||||
|
||||
// Prevent uploading recordings from being retrieved from REST API with "ready"
|
||||
// status. This will force their status back to "stopped" on GET until upload
|
||||
// process has finished
|
||||
@Override
|
||||
public void storeAsUploadingRecording(String recordingId) {
|
||||
recordingsBeingCurrentlyUploaded.add(recordingId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeingUploaded(String recordingId) {
|
||||
return recordingsBeingCurrentlyUploaded.contains(recordingId);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue