Skip to content
This repository was archived by the owner on Aug 21, 2024. It is now read-only.
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
2 changes: 1 addition & 1 deletion packages/client-core/src/social/services/InviteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export const InviteService = {

try {
const existingInviteResult = (await Engine.instance.api.service(invitePath).find({
query: data
query: { ...data, action: 'sent' }
})) as Paginated<InviteType>

let inviteResult
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/interfaces/UploadAssetInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export type AvatarUploadType = {
type: 'user-avatar-upload'
files: (Blob | Buffer)[]
userId?: UserID
path?: string
args: string | AvatarUploadArgsType
}

Expand Down
2 changes: 1 addition & 1 deletion packages/engine/src/avatar/state/AvatarNetworkState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ const AvatarReactor = React.memo(({ entityUUID }: { entityUUID: EntityUUID }) =>
}, [entityUUID])

useEffect(() => {
if (!state.avatarID.value) return
if (!isClient || !state.avatarID.value) return

let aborted = false

Expand Down
9 changes: 1 addition & 8 deletions packages/engine/src/recording/ECSRecordingSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,9 +476,7 @@ export const onStartRecording = async (action: ReturnType<typeof ECSRecordingAct
if (!createMediaRecording) return dispatchError('Media recording not available', action.$peer, action.$topic)

try {
const mediaRecorder = await createMediaRecording(recording.id, schema.peers)

activeRecording.mediaChannelRecorder = mediaRecorder
activeRecording.mediaChannelRecorder = await createMediaRecording(recording.id, schema.peers)

dispatchAction(
ECSRecordingActions.recordingStarted({
Expand Down Expand Up @@ -547,7 +545,6 @@ export const onStartPlayback = async (action: ReturnType<typeof ECSRecordingActi
const api = Engine.instance.api

const recording = await api.service(recordingPath).get(action.recordingID, { isInternal: true })
console.log(recording)

let schema = recording.schema

Expand Down Expand Up @@ -577,10 +574,6 @@ export const onStartPlayback = async (action: ReturnType<typeof ECSRecordingActi
resource.key.substring(resource.key.length - 3, resource.key.length) === '.ee'
)

const mediaFiles = recording.resources.filter(
(resource) => resource.key.substring(resource.key.length - 3, resource.key.length) !== '.ee'
)

const entityChunks = (await Promise.all(
entityFiles.map(async (resource) => {
const data = await fetch(resource.url)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
CPAL-1.0 License

The contents of this file are subject to the Common Public Attribution License
Version 1.0. (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
https://github.com/EtherealEngine/etherealengine/blob/dev/LICENSE.
The License is based on the Mozilla Public License Version 1.1, but Sections 14
and 15 have been added to cover use of software over a computer network and
provide for limited attribution for the Original Developer. In addition,
Exhibit A has been modified to be consistent with Exhibit B.

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
specific language governing rights and limitations under the License.

The Original Code is Ethereal Engine.

The Original Developer is the Initial Developer. The Initial Developer of the
Original Code is the Ethereal Engine team.

All portions of the code written by the Ethereal Engine team are Copyright © 2021-2023
Ethereal Engine. All Rights Reserved.
*/

export const recordingResourceUploadPath = 'recording-resource-upload'

export const recordingResourceUploadMethods = ['create'] as const
62 changes: 14 additions & 48 deletions packages/instanceserver/src/MediasoupRecordingSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,9 @@ import { DataChannelType } from '@etherealengine/common/src/interfaces/DataChann
import { PresentationSystemGroup } from '@etherealengine/engine/src/ecs/functions/EngineFunctions'
import { defineSystem } from '@etherealengine/engine/src/ecs/functions/SystemFunctions'
import { RecordingAPIState } from '@etherealengine/engine/src/recording/ECSRecordingSystem'
import { staticResourcePath } from '@etherealengine/engine/src/schemas/media/static-resource.schema'
import { recordingResourcePath } from '@etherealengine/engine/src/schemas/recording/recording-resource.schema'
import { recordingResourceUploadPath } from '@etherealengine/engine/src/schemas/recording/recording-resource-upload.schema'
import { RecordingID, RecordingSchemaType } from '@etherealengine/engine/src/schemas/recording/recording.schema'
import { getMutableState, none } from '@etherealengine/hyperflux'
import { getCachedURL } from '@etherealengine/server-core/src/media/storageprovider/getCachedURL'
import { getStorageProvider } from '@etherealengine/server-core/src/media/storageprovider/storageprovider'
import { PassThrough } from 'stream'
import { startFFMPEG } from './FFMPEG'
import { SocketWebRTCServerNetwork } from './SocketWebRTCServerFunctions'
Expand Down Expand Up @@ -212,43 +209,9 @@ type onUploadPartArgs = {
hash: string
}

export const uploadMediaStaticResource = async (props: onUploadPartArgs) => {
const api = Engine.instance.api

const storageProvider = getStorageProvider()

const uploadPromise = storageProvider.putObject({
Key: props.key,
Body: props.body,
ContentType: props.mimeType
})

const url = getCachedURL(props.key, storageProvider.cacheDomain)

const staticResource = await api.service(staticResourcePath).create(
{
hash: props.hash,
key: props.key,
url,
mimeType: props.mimeType
},
{ isInternal: true }
)

const recordingResource = await api.service(recordingResourcePath).create({
recordingId: props.recordingID,
staticResourceId: staticResource.id
})

await uploadPromise

await api.service(recordingResourcePath).patch(recordingResource.id, {
updatedAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
})
}

// todo - refactor to be in a reactor such that we can record media tracks that are started after the recording is
export const startMediaRecording = async (recordingID: RecordingID, schema: RecordingSchemaType['peers']) => {
const api = Engine.instance.api
const network = NetworkState.mediaNetwork as SocketWebRTCServerNetwork

const mediaStreams = {} as Record<PeerID, { [mediaType: string]: MediaTrackPair }>
Expand Down Expand Up @@ -295,15 +258,18 @@ export const startMediaRecording = async (recordingID: RecordingID, schema: Reco
.update(format)
.digest('hex')

return uploadMediaStaticResource({
recordingID,
key,
body: stream,
mimeType: format,
hash
}).then(() => {
logger.info('Uploaded media file' + key)
})
return api
.service(recordingResourceUploadPath)
.create({
recordingID,
key,
body: stream,
mimeType: format,
hash
})
.then(() => {
logger.info('Uploaded media file' + key)
})
})

logger.info('media recording started')
Expand Down
35 changes: 6 additions & 29 deletions packages/instanceserver/src/ServerHostNetworkSystem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,13 @@ import { updatePeers } from '@etherealengine/engine/src/networking/systems/Outgo
import { useEffect } from 'react'

import { RecordingAPIState } from '@etherealengine/engine/src/recording/ECSRecordingSystem'
import { staticResourcePath } from '@etherealengine/engine/src/schemas/media/static-resource.schema'
import { recordingResourcePath } from '@etherealengine/engine/src/schemas/recording/recording-resource.schema'
import { RecordingID } from '@etherealengine/engine/src/schemas/recording/recording.schema'
import { getMutableState, none } from '@etherealengine/hyperflux'

import { PeerID } from '@etherealengine/common/src/interfaces/PeerID'
import { SimulationSystemGroup } from '@etherealengine/engine/src/ecs/functions/EngineFunctions'
import { NetworkState } from '@etherealengine/engine/src/networking/NetworkState'
import { getCachedURL } from '@etherealengine/server-core/src/media/storageprovider/getCachedURL'
import { getStorageProvider } from '@etherealengine/server-core/src/media/storageprovider/storageprovider'
import { createStaticResourceHash } from '@etherealengine/server-core/src/media/upload-asset/upload-asset.service'
import { recordingResourceUploadPath } from '@etherealengine/engine/src/schemas/recording/recording-resource-upload.schema'
import { SocketWebRTCServerNetwork } from './SocketWebRTCServerFunctions'

export async function validateNetworkObjects(network: SocketWebRTCServerNetwork): Promise<void> {
Expand Down Expand Up @@ -67,30 +63,11 @@ export const uploadRecordingStaticResource = async (props: {
}) => {
const api = Engine.instance.api

const storageProvider = getStorageProvider()
await storageProvider.putObject({
Key: props.key,
Body: props.body,
ContentType: props.mimeType
})

const provider = getStorageProvider()
const url = getCachedURL(props.key, provider.cacheDomain)
const hash = createStaticResourceHash(props.body, { mimeType: props.mimeType, assetURL: props.key })

const staticResource = await api.service(staticResourcePath).create(
{
hash,
key: props.key,
url,
mimeType: props.mimeType
},
{ isInternal: true }
)

await api.service(recordingResourcePath).create({
staticResourceId: staticResource.id,
recordingId: props.recordingID
await api.service(recordingResourceUploadPath).create({
recordingID: props.recordingID,
key: props.key,
body: props.body,
mimeType: props.mimeType
})
}

Expand Down
3 changes: 1 addition & 2 deletions packages/instanceserver/src/SocketFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export const setupSocketFunctions = async (app: Application, spark: any) => {
const network = getServerNetwork(app)

const onAuthenticationRequest = async (data) => {
console.log(data)
const peerID = data.peerID

if (authTask) return
Expand Down Expand Up @@ -90,7 +89,7 @@ export const setupSocketFunctions = async (app: Application, spark: any) => {
{}
)
userId = authResult[identityProviderPath].userId as UserID
user = await app.service(userPath).get(userId)
user = await app.service(userPath).get(userId, { headers: spark.headers })

if (!user) {
authTask.status = 'fail'
Expand Down
Loading