Skip to main content

Documentation Index

Fetch the complete documentation index at: https://learn.social.plus/llms.txt

Use this file to discover all available pages before exploring further.

Manage Rooms

Manage room lifecycle including queries, updates, stream control, and deletion operations for interactive livestreaming.

Querying Rooms

Get Room by ID

Retrieve a single room with real-time updates:
let roomLiveObject = AmityRoomRepository.shared.getRoom(roomId: "room-123")

roomLiveObject.observe { room in
    print("Room: \(room.title)")
    print("Status: \(room.status)")
    print("Participants: \(room.participants.count)")
    print("Live URL: \(room.livePlaybackUrl ?? "Not live")")
}

Query Multiple Rooms

Get rooms with filtering and sorting:
let roomsCollection = AmityRoomRepository.shared.getRooms(
    statuses: [.live, .idle],
    types: [.coHosts],
    isDeleted: false,
    sortBy: .firstCreated
)

roomsCollection.observe { rooms in
    rooms.forEach { room in
        print("Room: \(room.title) - Status: \(room.status)")
    }
}

Query Live Rooms Only

Get currently broadcasting rooms:
let liveRooms = AmityRoomRepository.shared.getRooms(
    statuses: [.live],
    types: nil,
    isDeleted: false,
    sortBy: .lastCreated
)

liveRooms.observe { rooms in
    print("Currently live: \(rooms.count) rooms")
}

Query Parameters

Type: AmityRoomStatus[]
Required: No
Values: idle | live | waitingReconnect | ended | recorded
Filter rooms by their current status. Pass multiple statuses to match any.
Type: AmityRoomType[]
Required: No
Values: coHosts
Filter rooms by type.
Type: boolean
Required: No
Default: false
Include or exclude deleted rooms.
Type: AmityRoomSortOption
Required: No
Values: firstCreated | lastCreated
Default: firstCreated
Sort rooms by creation date.

Updating Rooms

Update room details (creator only):
Task { @MainActor in
    do {
        let updatedRoom = try await AmityRoomRepository.shared.updateRoom(
            roomId: "room-123",
            title: "Updated Room Title",
            description: "New description with updated details",
            thumbnailFileId: "new-thumbnail-file-id",
            metadata: ["category": "updated"],
            channelEnabled: true
        )
        print("Room updated: \(updatedRoom.title)")
    } catch {
        print("Failed to update room: \(error)")
    }
}
Updatable Fields: Only title, description, thumbnailFileId, metadata, and channelEnabled can be updated. Participants and room type cannot be changed after creation.

Stopping a Stream

Stop an active broadcast:
Task { @MainActor in
    do {
        try await AmityRoomRepository.shared.stop(roomId: "room-123")
        print("Stream stopped successfully")
    } catch {
        print("Failed to stop stream: \(error)")
    }
}
Stream Status: Stopping a stream changes the room status to “ended”. The stream cannot be restarted in the same room.

Getting Recorded URLs

Retrieve recorded stream URLs after broadcast ends:
Task { @MainActor in
    do {
        let recordedUrls = try await AmityRoomRepository.shared.getRecordedUrls(
            roomId: "room-123"
        )
        
        if recordedUrls.isEmpty {
            print("No recordings available")
        } else {
            recordedUrls.forEach { url in
                print("Recording URL: \(url)")
            }
        }
    } catch {
        print("Failed to get recorded URLs: \(error)")
    }
}
Recording Availability: Recordings are available after the room status changes to “recorded”. This may take some time after the stream ends.

Common Patterns

Monitor Room Status

Track room status changes in real-time:
let roomLiveObject = AmityRoomRepository.shared.getRoom(roomId: roomId)

roomLiveObject.observe { room in
    switch room.status {
    case .idle:
        showStatus("Room created, ready to start")
        enableStartButton()
        
    case .live:
        showStatus("Broadcasting live")
        updateViewerCount()
        enableStopButton()
        
    case .waitingReconnect:
        showStatus("Reconnecting...")
        showReconnectingUI()
        
    case .ended:
        showStatus("Stream ended")
        disableStreamControls()
        checkForRecording()
        
    case .recorded:
        showStatus("Recording available")
        enablePlaybackButton()
    }
}

Display Live Rooms List

Show currently active broadcasts:
Automatic Thumbnails: When a room is live, the backend automatically populates liveThumbnailUrl with an auto-generated thumbnail from the stream. Use this as a fallback when no creator-uploaded thumbnail (thumbnailFileId) is available. See Rooms Overview - Automatic Thumbnail Generation for the complete fallback chain.
let liveRooms = AmityRoomRepository.shared.getRooms(
    statuses: [.live],
    types: [.coHosts],
    isDeleted: false,
    sortBy: .lastCreated
)

liveRooms.observe { rooms in
    let roomList = rooms.map { room in
        RoomListItem(
            roomId: room.roomId,
            title: room.title,
            thumbnail: room.getThumbnail()?.fileUrl,
            participantCount: room.participants.count,
            playbackUrl: room.livePlaybackUrl,
            channelId: room.channelId
        )
    }
    updateLiveRoomsList(roomList)
}

Stream Lifecycle Management

Complete stream management workflow:
// Start streaming
func startStreaming(roomId: String) async {
    do {
        let broadcasterData = try await AmityRoomRepository.shared.getBroadcastData(
            roomId: roomId
        )
        
        if case .coHosts(let token, let url) = broadcasterData {
            try await initializeLiveKit(url: url, token: token)
        }
        
        try await beginBroadcast()
        print("Streaming started")
    } catch {
        print("Failed to start streaming: \(error)")
    }
}

// Stop streaming
func stopStreaming(roomId: String) async {
    do {
        endBroadcast()
        try await AmityRoomRepository.shared.stop(roomId: roomId)
        print("Streaming stopped")
        
        // Wait for recording
        DispatchQueue.main.asyncAfter(deadline: .now() + 30) {
            Task {
                if let urls = try? await AmityRoomRepository.shared.getRecordedUrls(roomId: roomId),
                   let firstUrl = urls.first {
                    print("Recording available: \(firstUrl)")
                }
            }
        }
    } catch {
        print("Failed to stop streaming: \(error)")
    }
}

Best Practices

Monitor room status for better UX:
  • Subscribe to room updates for real-time status
  • Handle all status transitions appropriately
  • Show appropriate UI for each status
  • Auto-reconnect on temporary disconnections
Implement proper stream controls:
  • Validate room status before starting/stopping
  • Provide clear feedback to users
  • Handle network interruptions gracefully
  • Implement timeout mechanisms
Manage recordings effectively:
  • Poll for recordings after stream ends
  • Store recording URLs for playback
  • Implement retry logic for unavailable recordings
  • Clean up old recordings
Optimize resource usage:
  • Unsubscribe from live collections when not needed
  • Delete ended rooms after recording retrieval
  • Limit concurrent live room queries
  • Cache frequently accessed room data

Permission Checks

Verify permissions before operations:
// Check if user can stop/delete room
let roomLiveObject = AmityRoomRepository.shared.getRoom(roomId: roomId)

roomLiveObject.observe { room in
    let isCreator = room.creatorId == AmityCoreClient.currentUserId
    let isHost = room.participants.first { $0.type == .host && $0.userId == AmityCoreClient.currentUserId } != nil
    let isCoHost = room.participants.first { $0.type == .coHost && $0.userId == AmityCoreClient.currentUserId } != nil
    
    if isCreator || isHost {
        // User can stop or delete the room
        showStreamControls()
    } else if isCoHost {
        // Co-host can leave but not stop/delete
        showCoHostControls()
    } else {
        // User is viewer
        showViewerControls()
    }
}

Error Handling

do {
    try await AmityRoomRepository.shared.stop(roomId: roomId)
} catch AmityError.permissionDenied {
    showError("You don't have permission to stop this stream")
} catch AmityError.notFound {
    showError("Room not found")
} catch AmityError.invalidStatus {
    showError("Stream is not currently active")
} catch {
    showError("Failed to stop stream: \(error.localizedDescription)")
}

Start Broadcasting

Connect to LiveKit and go live

Co-Host Management

Invite and manage co-hosts

Create Room

Set up new rooms