Menerbitkan & Berlangganan dengan Siaran IVS iOS SDK | Streaming Waktu Nyata - Amazon IVS

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Menerbitkan & Berlangganan dengan Siaran IVS iOS SDK | Streaming Waktu Nyata

Dokumen ini membawa Anda melalui langkah-langkah yang terlibat dalam penerbitan dan berlangganan ke panggung menggunakan siaran SDK iOS streaming IVS waktu nyata.

Konsep

Tiga konsep inti mendasari fungsionalitas real-time: panggung, strategi, dan penyaji. Tujuan desain adalah meminimalkan jumlah logika sisi klien yang diperlukan untuk membangun produk yang berfungsi.

Stage

IVSStageKelas adalah titik utama interaksi antara aplikasi host danSDK. Kelas mewakili panggung itu sendiri dan digunakan untuk bergabung dan meninggalkan panggung. Membuat atau bergabung dengan tahap memerlukan string token yang valid dan belum kedaluwarsa dari bidang kontrol (direpresentasikan sebagaitoken). Bergabung dan meninggalkan panggung itu sederhana.

let stage = try IVSStage(token: token, strategy: self) try stage.join() stage.leave()

IVSStageKelas juga adalah tempat IVSStageRenderer dan IVSErrorDelegate dapat dilampirkan:

let stage = try IVSStage(token: token, strategy: self) stage.errorDelegate = self stage.addRenderer(self) // multiple renderers can be added

Strategi

IVSStageStrategyProtokol menyediakan cara bagi aplikasi host untuk mengkomunikasikan keadaan panggung yang diinginkan keSDK. Tiga fungsi perlu diimplementasikan:shouldSubscribeToParticipant,shouldPublishParticipant, danstreamsToPublishForParticipant. Semua dibahas di bawah ini.

Berlangganan Peserta

func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType

Ketika peserta jarak jauh bergabung dengan panggung, SDK pertanyaan aplikasi host tentang status langganan yang diinginkan untuk peserta tersebut. Pilihannya adalah.none,.audioOnly, dan.audioVideo. Saat mengembalikan nilai untuk fungsi ini, aplikasi host tidak perlu khawatir tentang status publikasi, status langganan saat ini, atau status koneksi tahap. Jika .audioVideo dikembalikan, SDK menunggu hingga peserta jarak jauh mempublikasikan sebelum berlangganan, dan memperbarui aplikasi host melalui penyaji selama proses berlangsung.

Berikut adalah contoh implementasi:

func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType { return .audioVideo }

Ini adalah implementasi lengkap dari fungsi ini untuk aplikasi host yang selalu ingin semua peserta saling bertemu; misalnya, aplikasi obrolan video.

Implementasi yang lebih maju juga dimungkinkan. Gunakan attributes properti IVSParticipantInfo untuk berlangganan peserta secara selektif berdasarkan atribut yang disediakan server:

func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType { switch participant.attributes["role"] { case "moderator": return .none case "guest": return .audioVideo default: return .none } }

Ini dapat digunakan untuk membuat panggung di mana moderator dapat memantau semua tamu tanpa terlihat atau didengar sendiri. Aplikasi host dapat menggunakan logika bisnis tambahan untuk membiarkan moderator melihat satu sama lain tetapi tetap tidak terlihat oleh tamu.

Konfigurasi untuk Berlangganan Peserta

func stage(_ stage: IVSStage, subscribeConfigurationForParticipant participant: IVSParticipantInfo) -> IVSSubscribeConfiguration

Jika peserta jarak jauh sedang berlangganan (lihat Berlangganan Peserta), akan SDK menanyakan aplikasi host tentang konfigurasi langganan khusus untuk peserta tersebut. Konfigurasi ini bersifat opsional dan memungkinkan aplikasi host untuk mengontrol aspek-aspek tertentu dari perilaku pelanggan. Untuk informasi tentang apa yang dapat dikonfigurasi, lihat SubscribeConfigurationdi dokumentasi SDK referensi.

Berikut adalah contoh implementasi:

func stage(_ stage: IVSStage, subscribeConfigurationForParticipant participant: IVSParticipantInfo) -> IVSSubscribeConfiguration { let config = IVSSubscribeConfiguration() try! config.jitterBuffer.setMinDelay(.medium()) return config }

Implementasi ini memperbarui penundaan minimum jitter-buffer untuk semua peserta berlangganan ke preset. MEDIUM

Seperti halnyashouldSubscribeToParticipant, implementasi yang lebih maju dimungkinkan. Yang diberikan ParticipantInfo dapat digunakan untuk memperbarui konfigurasi berlangganan secara selektif untuk peserta tertentu.

Sebaiknya gunakan perilaku default. Tentukan konfigurasi khusus hanya jika ada perilaku tertentu yang ingin Anda ubah.

Publikasi

func stage(_ stage: IVSStage, shouldPublishParticipant participant: IVSParticipantInfo) -> Bool

Setelah terhubung ke panggung, SDK kueri aplikasi host untuk melihat apakah peserta tertentu harus mempublikasikan. Ini hanya dipanggil pada peserta lokal yang memiliki izin untuk mempublikasikan berdasarkan token yang disediakan.

Berikut adalah contoh implementasi:

func stage(_ stage: IVSStage, shouldPublishParticipant participant: IVSParticipantInfo) -> Bool { return true }

Ini untuk aplikasi obrolan video standar di mana pengguna selalu ingin mempublikasikan. Mereka dapat membisukan dan menonaktifkan audio dan video mereka, untuk langsung disembunyikan atau seen/heard. (They also can use publish/unpublish, but that is much slower. Mute/unmute lebih disukai untuk kasus penggunaan di mana mengubah visibilitas sering diinginkan.)

Memilih Streaming untuk Publikasikan

func stage(_ stage: IVSStage, streamsToPublishForParticipant participant: IVSParticipantInfo) -> [IVSLocalStageStream]

Saat menerbitkan, ini digunakan untuk menentukan aliran audio dan video apa yang harus dipublikasikan. Ini dibahas secara lebih rinci nanti di Publish a Media Stream.

Memperbarui Strategi

Strategi ini dimaksudkan untuk menjadi dinamis: nilai yang dikembalikan dari salah satu fungsi di atas dapat diubah kapan saja. Misalnya, jika aplikasi host tidak ingin mempublikasikan sampai pengguna akhir mengetuk tombol, Anda dapat mengembalikan variabel dari shouldPublishParticipant (sesuatu sepertihasUserTappedPublishButton). Ketika variabel itu berubah berdasarkan interaksi oleh pengguna akhir, panggil stage.refreshStrategy() untuk memberi sinyal kepada SDK bahwa ia harus menanyakan strategi untuk nilai terbaru, hanya menerapkan hal-hal yang telah berubah. Jika SDK mengamati bahwa shouldPublishParticipant nilainya telah berubah, itu akan memulai proses publikasi. Jika SDK kueri dan semua fungsi mengembalikan nilai yang sama seperti sebelumnya, refreshStrategy panggilan tidak akan membuat modifikasi apa pun pada panggung.

Jika nilai pengembalian shouldSubscribeToParticipant perubahan dari .audioVideo ke.audioOnly, aliran video akan dihapus untuk semua peserta dengan nilai yang dikembalikan diubah, jika aliran video ada sebelumnya.

Umumnya, tahap menggunakan strategi untuk menerapkan perbedaan antara strategi sebelumnya dan saat ini secara efisien, tanpa aplikasi host perlu khawatir tentang semua keadaan yang diperlukan untuk mengelolanya dengan benar. Karena itu, anggap menelepon stage.refreshStrategy() sebagai operasi yang murah, karena tidak melakukan apa-apa kecuali strateginya berubah.

Penyaji

IVSStageRendererProtokol mengkomunikasikan keadaan panggung ke aplikasi host. Pembaruan pada UI aplikasi host biasanya dapat didukung sepenuhnya oleh peristiwa yang disediakan oleh perender. Penyaji menyediakan fungsi-fungsi berikut:

func stage(_ stage: IVSStage, participantDidJoin participant: IVSParticipantInfo) func stage(_ stage: IVSStage, participantDidLeave participant: IVSParticipantInfo) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChange publishState: IVSParticipantPublishState) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChange subscribeState: IVSParticipantSubscribeState) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didAdd streams: [IVSStageStream]) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didRemove streams: [IVSStageStream]) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChangeMutedStreams streams: [IVSStageStream]) func stage(_ stage: IVSStage, didChange connectionState: IVSStageConnectionState, withError error: Error?)

Tidak diharapkan bahwa informasi yang diberikan oleh penyaji berdampak pada nilai pengembalian strategi. Misalnya, nilai pengembalian shouldSubscribeToParticipant tidak diharapkan berubah ketika participant:didChangePublishState dipanggil. Jika aplikasi host ingin berlangganan ke peserta tertentu, itu harus mengembalikan jenis langganan yang diinginkan terlepas dari status publikasi peserta tersebut. Bertanggung SDK jawab untuk memastikan bahwa keadaan strategi yang diinginkan ditindaklanjuti pada waktu yang tepat berdasarkan keadaan panggung.

Perhatikan bahwa hanya peserta penerbitan yang dipicuparticipantDidJoin, dan setiap kali peserta berhenti menerbitkan atau meninggalkan sesi panggung, participantDidLeave dipicu.

Publikasikan Aliran Media

Perangkat lokal seperti mikrofon dan kamera internal ditemukan melaluiIVSDeviceDiscovery. Berikut adalah contoh memilih kamera yang menghadap ke depan dan mikrofon default, lalu mengembalikannya seperti yang akan IVSLocalStageStreams dipublikasikan oleh: SDK

let devices = IVSDeviceDiscovery().listLocalDevices() // Find the camera virtual device, choose the front source, and create a stream let camera = devices.compactMap({ $0 as? IVSCamera }).first! let frontSource = camera.listAvailableInputSources().first(where: { $0.position == .front })! camera.setPreferredInputSource(frontSource) let cameraStream = IVSLocalStageStream(device: camera) // Find the microphone virtual device and create a stream let microphone = devices.compactMap({ $0 as? IVSMicrophone }).first! let microphoneStream = IVSLocalStageStream(device: microphone) // Configure the audio manager to use the videoChat preset, which is optimized for bi-directional communication, including echo cancellation. IVSStageAudioManager.sharedInstance().setPreset(.videoChat) // This is a function on IVSStageStrategy func stage(_ stage: IVSStage, streamsToPublishForParticipant participant: IVSParticipantInfo) -> [IVSLocalStageStream] { return [cameraStream, microphoneStream] }

Tampilkan dan Hapus Peserta

Setelah berlangganan selesai, Anda akan menerima array IVSStageStream objek melalui fungsi renderer. didAddStreams Untuk melihat pratinjau atau menerima statistik tingkat audio tentang peserta ini, Anda dapat mengakses IVSDevice objek yang mendasarinya dari aliran:

if let imageDevice = stream.device as? IVSImageDevice { let preview = imageDevice.previewView() /* attach this UIView subclass to your view */ } else if let audioDevice = stream.device as? IVSAudioDevice { audioDevice.setStatsCallback( { stats in /* process stats.peak and stats.rms */ }) }

Ketika peserta berhenti menerbitkan atau berhenti berlangganan, didRemoveStreams fungsi dipanggil dengan aliran yang telah dihapus. Aplikasi host harus menggunakan ini sebagai sinyal untuk menghapus aliran video peserta dari hierarki tampilan.

didRemoveStreamsdipanggil untuk semua skenario di mana aliran mungkin dihapus, termasuk:

  • Peserta jarak jauh berhenti menerbitkan.

  • Perangkat lokal berhenti berlangganan atau mengubah langganan dari ke.audioVideo. .audioOnly

  • Peserta jarak jauh meninggalkan panggung.

  • Peserta lokal meninggalkan panggung.

Karena didRemoveStreams dipanggil untuk semua skenario, tidak diperlukan logika bisnis khusus untuk menghapus peserta dari UI selama operasi cuti jarak jauh atau lokal.

Bisukan dan Bunyikan Streaming Media

IVSLocalStageStreamobjek memiliki setMuted fungsi yang mengontrol apakah aliran diredam. Fungsi ini dapat dipanggil pada aliran sebelum atau sesudah dikembalikan dari fungsi streamsToPublishForParticipant strategi.

Penting: Jika instance IVSLocalStageStream objek baru dikembalikan streamsToPublishForParticipant setelah panggilan kerefreshStrategy, status bisu objek aliran baru diterapkan ke panggung. Hati-hati saat membuat IVSLocalStageStream instance baru untuk memastikan status bisu yang diharapkan dipertahankan.

Pantau Status Bisu Media Peserta Jarak Jauh

Saat peserta mengubah status bisu aliran video atau audionya, didChangeMutedStreams fungsi penyaji dipanggil dengan larik aliran yang telah berubah. Gunakan isMuted properti IVSStageStream untuk memperbarui UI Anda sesuai dengan itu:

func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChangeMutedStreams streams: [IVSStageStream]) { streams.forEach { stream in /* stream.isMuted */ } }

Buat Konfigurasi Panggung

Untuk menyesuaikan nilai konfigurasi video panggung, gunakanIVSLocalStageStreamVideoConfiguration:

let config = IVSLocalStageStreamVideoConfiguration() try config.setMaxBitrate(900_000) try config.setMinBitrate(100_000) try config.setTargetFramerate(30) try config.setSize(CGSize(width: 360, height: 640)) config.degradationPreference = .balanced

Dapatkan RTC Statistik Web

Untuk mendapatkan RTC statistik Web terbaru untuk aliran penerbitan atau aliran berlangganan, gunakan requestRTCStats terusIVSStageStream. Ketika koleksi selesai, Anda akan menerima statistik melalui IVSStageStreamDelegate yang dapat diaturIVSStageStream. Untuk terus mengumpulkan RTC statistik Web, panggil fungsi ini di file. Timer

func stream(_ stream: IVSStageStream, didGenerateRTCStats stats: [String : [String : String]]) { for stat in stats { for member in stat.value { print("stat \(stat.key) has member \(member.key) with value \(member.value)") } } }

Dapatkan Atribut Peserta

Jika Anda menentukan atribut dalam permintaan CreateParticipantToken titik akhir, Anda dapat melihat atribut di IVSParticipantInfo properti:

func stage(_ stage: IVSStage, participantDidJoin participant: IVSParticipantInfo) { print("ID: \(participant.participantId)") for attribute in participant.attributes { print("attribute: \(attribute.key)=\(attribute.value)") } }

Lanjutkan Sesi di Latar Belakang

Saat aplikasi memasuki latar belakang, Anda dapat terus berada di panggung sambil mendengar audio jarak jauh, meskipun tidak mungkin untuk terus mengirim gambar dan audio Anda sendiri. Anda perlu memperbarui IVSStrategy implementasi Anda untuk berhenti menerbitkan dan berlangganan .audioOnly (atau.none, jika ada):

func stage(_ stage: IVSStage, shouldPublishParticipant participant: IVSParticipantInfo) -> Bool { return false } func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType { return .audioOnly }

Kemudian buat panggilan kestage.refreshStrategy().

Aktifkan/Nonaktifkan Layered Encoding dengan Simulcast

Saat menerbitkan aliran media, SDK mentransmisikan aliran video berkualitas tinggi dan berkualitas rendah, sehingga peserta jarak jauh dapat berlangganan streaming meskipun mereka memiliki bandwidth downlink terbatas. Pengkodean berlapis dengan simulcast aktif secara default. Anda dapat menonaktifkannya denganIVSSimulcastConfiguration:

// Disable Simulcast let config = IVSLocalStageStreamVideoConfiguration() config.simulcast.enabled = false let cameraStream = IVSLocalStageStream(device: camera, configuration: config) // Other Stage implementation code

Siarkan Panggung ke IVS Saluran

Untuk menyiarkan panggung, buat yang terpisah IVSBroadcastSession dan kemudian ikuti instruksi biasa untuk penyiaran denganSDK, dijelaskan di atas. deviceProperti pada IVSStageStream akan berupa IVSImageDevice atau IVSAudioDevice seperti yang ditunjukkan pada cuplikan di atas; ini dapat dihubungkan ke IVSBroadcastSession.mixer untuk menyiarkan seluruh tahap dalam tata letak yang dapat disesuaikan.

Secara opsional, Anda dapat menggabungkan panggung dan menyiarkannya ke saluran IVS latensi rendah, untuk menjangkau audiens yang lebih besar. Lihat Mengaktifkan Beberapa Host di Amazon IVS Stream di Panduan Pengguna Streaming IVS Latensi Rendah.