Phát triển ứng dụng xã hội âm thanh đã trở thành tiêu chuẩn trong các ứng dụng di động hiện đại. Dù là phòng karaoke, chơi game nhóm hay giao lưu bạn bè, tính năng này đều rất cần thiết. Thay vì phát triển từ đầu, ZegoSDK cung cấp giải pháp hoàn chỉnh giúp bạn xây dựng nhanh chóng - không chỉ đơn giản hóa quá trình phát triển mà còn đảm bảo chất lượng âm thanh ổn định. Bài viết này sẽ hướng dẫn bạn cách triển khai một phòng chat giọng nói hiệu quả.
Một số ứng dụng điển hình
- Chat 1-1: Kết nối người dùng ngẫu nhiên hoặc được chỉ định, cung cấp cuộc gọi thoại rõ ràng và mượt mà
- Phòng karaoke trực tuyến: Thư viện bài hát lớn, hỗ trợ hát đơn, hợp xướng và nhiều tính năng tương tác khác
- Chat nhóm game: Tạo phòng chat âm thanh cho game, giúp đội nhóm phối hợp và cải thiện trải nghiệm
- Radio giọng nói: Chủ trì livestream âm thanh, khán giả có thể tương tác và yêu cầu tham gia
- Hẹn hò trực tuyến: Nhiều người tham gia cùng lúc, khán giả có thể tương tác và tặng quà
- Đồng hành AI: Trò chuyện với nhân vật giọng nói thông minh, hỗ trợ tương tác cốt truyện và cảm xúc
Mặc dù logic kinh doanh khác nhau giữa các kịch bản, nhưng tất cả đều dựa trên nền tảng công nghệ chung: âm thanh/video thời gian thực chất lượng cao + giao tiếp tức thời ổn định.
Tại sao chọn ZegoSDK?
- Xử lý âm thanh hiệu suất cao: ZegoSDK cung cấp mã hóa/giải mã âm thanh chất lượng cao và xử lý 3A
- Giao tiếp độ trễ thấp: Triển khai nút toàn cầu, đảm bảo âm thanh thời gian thực mượt mà
- Giải pháp hoàn chỉnh: Cung cấp tài liệu tham khảo triển khai logic kinh doanh phòng chat giọng nói
- Ổn định đáng tin cậy: SDK cấp thương mại đã được xác thực bởi hàng triệu người dùng
- Thân thiện với nhà phát triển: Tài liệu và mã ví dụ hoàn chỉnh, dễ上手
Cách tiếp cận và kết quả thực hiện
Trước khi bắt đầu coding, hãy xác định mục tiêu và sắp xếp ý tưởng.
Nguyên lý kỹ thuật:
- Tất cả người nghe vào phòng có thể bắt đầu kéo luồng để phát âm thanh của người phát biểu.
- Người phát biểu có thể bắt đầu đẩy luồng sau khi lên mic, gửi âm thanh cục bộ đến người nghe trong phòng.
Kết quả thực hiện:
Bằng cách tuân theo quy trình kỹ thuật này, chúng ta có thể đạt được:
| Trang chủ | Trang chủ phòng | Trang người nghe | Người nghe yêu cầu lên mic | Chủ phòng xem yêu cầu |
Chuẩn bị dự án
- Đăng ký tài khoản nhà phát triển Zego, tạo dự án và lấy App ID và密钥 SDK
- Mở dịch vụ "Giao tiếp tức thời" trong bảng điều khiển
Quy trình kỹ thuật triển khai phòng chat giọng nói iOS
Các bước cụ thể: Tích hợp Express SDK → Khởi tạo engine → Đăng nhập phòng → Tích hợp ZIM SDK → Quản lý mic → Chế độ phòng → Đẩy/kéo luồng
Tích hợp Zego Express SDK vào dự án:
https://github.com/zegolibrary/express-audio-ios
Khởi tạo SDK: Sử dụng AppID và Server để tạo instance engine
let profile = ZegoEngineProfile()
profile.appID = <#appID#>
profile.appSign = <#appSign#>
profile.scenario = .broadcast
ZegoExpressEngine.createEngine(with: profile, eventHandler: self)
Đăng nhập phòng: Tham gia cùng phòng bằng userID, roomID và token
let roomID = "room1"
let user = ZegoUser(userID: "user1")
let config = ZegoRoomConfig()
config.isUserStatusNotify = true
ZegoExpressEngine.shared().loginRoom(roomID, user: user, config: config) { errorCode, extendedData in
if (errorCode == 0) {
NSLog("Đăng nhập phòng thành công")
} else {
NSLog("Đăng nhập phòng thất bại")
}
}
Tích hợp và sử dụng ZIM SDK
https://github.com/zegolibrary/zim-ios
func initWithAppID(_ appID: UInt32, appSign: String?) {
let zimConfig: ZIMAppConfig = ZIMAppConfig()
zimConfig.appID = appID
zimConfig.appSign = appSign
self.zim = ZIM.shared()
if self.zim == nil {
self.zim = ZIM.create(with: zimConfig)
}
self.zim?.setEventHandler(self)
}
Quản lý mic
- Người nghe lên mic, gọi setRoomAttributes và sử dụng số thứ tự mic làm Key, userID của người nghe làm giá trị của thuộc tính phòng. Nếu thành công, người nghe có thể bắt đầu đẩy luồng.
func takeSeat(seatIndex: Int, callback: ZIMRoomAttributesOperatedCallback?) {
guard let localUser = ZegoSDKManager.shared.currentUser else { return }
ZegoSDKManager.shared.zimService.setRoomAttributes("\(seatIndex)", value: localUser.id) { roomID, errorKeys, errorInfo in
guard let callback = callback else { return }
callback(roomID,errorKeys,errorInfo)
}
}
- Người phát biểu xuống mic, có thể gọi deleteRoomAttributesByKeys để xóa số mic đang sử dụng và dừng đẩy luồng.
func leaveSeat(seatIndex: Int, callback: ZIMRoomAttributesOperatedCallback?) {
ZegoSDKManager.shared.zimService.deletedRoomAttributes(["\(seatIndex)"]) { roomID, errorKeys, errorInfo in
guard let callback = callback else { return }
callback(roomID,errorKeys,errorInfo)
}
}
Chế độ phòng
Chế độ phòng được định nghĩa là: Chế độ tự do {"lockseat":false} và chế độ yêu cầu {"lockseat":true}
func lockSeat(_ lock: Bool) {
roomExtraInfoDict.updateValue(lock as AnyObject, forKey: "lockseat")
ZegoSDKManager.shared.expressService.setRoomExtraInfo(key: KEY, value: roomExtraInfoDict.jsonString)
}
Đẩy/kéo luồng: Thu thập và đẩy luồng âm thanh/video cục bộ, kéo và hiển thị luồng từ xa
Xem trước hình ảnh của mình và đẩy luồng đến ZEGO Cloud, trong cuộc gọi video, chúng ta cần kéo và hiển thị âm thanh/video của người dùng khác.
// Xem trước
let previewCanvas = ZegoCanvas(view: localUserViewObject.view.view)
ZegoExpressEngine.shared().startPreview(previewCanvas)
ZegoExpressEngine.shared().startPublishingStream(localStreamID)
// Kéo luồng âm thanh/video của người dùng khác
func onRoomStreamUpdate(_ updateType: ZegoUpdateType, streamList: [ZegoStream], extendedData: [AnyHashable: Any]?, roomID: String) {
if updateType == .add {
let streamID = streamList[0].streamID
ZegoExpressEngine.shared().startPlayingStream(streamID, canvas: ZegoCanvas(view: viewObject.view.view))
}
}
Câu hỏi thường gặp và giải pháp
Câu hỏi 1: Khởi tạo SDK thất bại hoặc không thể tham gia phòng
Giải pháp:
- Xác nhận AppID và AppSign chính xác và dịch vụ đã được kích hoạt
- Kiểm tra kết nối mạng và cài đặt tường lửa
- Xác thực tính hiệu lực của Token
Câu hỏi 2: Vang, nhiễu, gián đoạn âm thanh
Giải pháp:
- Bật xử lý 3A tích hợp trong SDK (loại bỏ vang, giảm nhiễu, điều khiển tăng âm)
- Tối ưu hóa cấu hình tham số âm thanh theo kịch bản
- Hướng dẫn người dùng kiểm tra quyền microphone và trạng thái thiết bị
Câu hỏi 3: Người dùng thấy trạng thái mic không nhất quán
Giải pháp:
- Quản lý trạng thái mic thông qua thuộc tính phòng ZIM
- Thêm cơ chế chống xung đột cho các thao tác quan trọng
- Đồng bộ trạng thái mới sau khi reconnect
Câu hỏi 4: Tin nhắn IM gửi thất bại hoặc chậm
Giải pháp:
- Xác nhận ZIM SDK đã được khởi tạo và đăng nhập thành công
- Kiểm tra chất lượng mạng, tự động thử lại tin nhắn thất bại
- Sử dụng chế độ gửi tin nhắn đáng tin cậy cho tin nhắn quan trọng
Câu hỏi 5: Chế độ tự do/yêu cầu không có hiệu lực sau khi chuyển đổi
Giải pháp:
- Đảm bảo kiểm tra quyền hạn của chủ phòng chính xác
- Kiểm tra xem thuộc tính phòng có được phát sóng đến tất cả thành viên không
- Xác thực logic kiểm soát quyền hạn chuyển đổi chế độ