HomeiOS Developmentios - Reconnect by way of RTMP utilizing Haishinkit to the server...

ios – Reconnect by way of RTMP utilizing Haishinkit to the server creates loop


I am attempting to create a transcriber utilizing this api https://docs.rev.ai/api/streaming/requests/#rtmp-streams , for audio streaming I take advantage of Haishinkit. While you join for the primary time, the stream works appropriately and the API returns textual content. I’ve a button the place the consumer can choose a language; when deciding on a language, the websocket is disconnected and the stream ends, then I attempt to reconnect: ship a request to the api to get hyperlinks for the stream and the identify of the stream, however once I restart the stream I get these messages within the console:

2024-16-01 13:36:32.951 [Info] [com.haishinkit.HaishinKit] [RTMPNWSocket.swift:168] stateDidChange(to:) > Connection is prepared.
2024-16-01 13:36:32.953 [Info] [com.haishinkit.HaishinKit] [RTMPNWSocket.swift:159] viabilityDidChange(to:) > Connection viability modified to true
NetConnection.Join.Success
2024-16-01 13:36:34.158 [Info] [com.haishinkit.HaishinKit] [IOAudioResampler.swift:227] setUp(_:) > inputFormat:<AVAudioFormat 0x2804f00a0: 1 ch, 48000 Hz, Int16>,outputFormat:<AVAudioFormat 0x2804f25d0: 1 ch, 48000 Hz, Int16>
2024-16-01 13:36:34.158 [Info] [com.haishinkit.HaishinKit] [AudioCodec.swift:149] makeAudioConverter() > inputFormat:<AVAudioFormat 0x2804f25d0: 1 ch, 48000 Hz, Int16>,outputFormat:<AVAudioFormat 0x2804f06e0: 1 ch, 48000 Hz, aac (0x00000002) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/body>
2024-16-01 13:36:34.440 [Error] [com.haishinkit.HaishinKit] [RTMPMessage.swift:309] payload > AMF0Serializer{knowledge: 14 bytes,place: 14,reference: HaishinKit.AMFReference}
NetStream.Publish.Begin
NetConnection.Name.Failed
2024-01-16 13:36:37.219701+0300 AmazingTranscriber[1972:138995] [tcp] tcp_input [C5.1.1:2] flags=[R] seq=2497584374, ack=4294967196, win=0 state=CLOSE_WAIT rcv_nxt=2497584375, snd_una=1639471199
2024-01-16 13:36:37.251997+0300 AmazingTranscriber[1972:138995] [] nw_flow_prepare_output_frames Failing the write requests [57: Socket is not connected]
2024-01-16 13:36:37.252031+0300 AmazingTranscriber[1972:138995] [connection] nw_write_request_report [C5] Ship failed with error “Socket just isn’t related”
2024-16-01 13:36:37.252 [Warn] [com.haishinkit.HaishinKit] [RTMPConnection.swift:403] on(standing:) >
2024-01-16 13:36:37.252199+0300 AmazingTranscriber[1972:138995] [tcp] tcp_output [C5.1.1:2] flags=[R.] seq=1639475405, ack=2497584375, win=2048 state=CLOSED rcv_nxt=2497584375, snd_una=1639471199
NetConnection.Join.Closed
2024-16-01 13:36:39.151 [Info] [com.haishinkit.HaishinKit] [RTMPNWSocket.swift:168] stateDidChange(to:) > Connection is prepared.
2024-16-01 13:36:39.152 [Info] [com.haishinkit.HaishinKit] [RTMPNWSocket.swift:159] viabilityDidChange(to:) > Connection viability modified to true
NetConnection.Join.Success
2024-16-01 13:36:40.891 [Error] [com.haishinkit.HaishinKit] [RTMPMessage.swift:309] payload > AMF0Serializer{knowledge: 14 bytes,place: 14,reference: HaishinKit.AMFReference}
NetStream.Publish.Begin
NetConnection.Name.Failed
2024-01-16 13:36:43.799807+0300 AmazingTranscriber[1972:138993] [tcp] tcp_input [C6.1.1:2] flags=[R] seq=3439027247, ack=4294967196, win=0 state=CLOSE_WAIT rcv_nxt=3439027248, snd_una=3732763433
2024-01-16 13:36:43.864706+0300 AmazingTranscriber[1972:138993] [] nw_flow_prepare_output_frames Failing the write requests [57: Socket is not connected]
2024-01-16 13:36:43.864738+0300 AmazingTranscriber[1972:138993] [connection] nw_write_request_report [C6] Ship failed with error “Socket just isn’t related”
2024-16-01 13:36:43.865 [Warn] [com.haishinkit.HaishinKit] [RTMPConnection.swift:403] on(standing:) >
2024-01-16 13:36:43.864895+0300 AmazingTranscriber[1972:138993] [tcp] tcp_output [C6.1.1:2] flags=[R.] seq=3732767695, ack=3439027248, win=2048 state=CLOSED rcv_nxt=3439027248, snd_una=3732763433
NetConnection.Join.Closed

Please inform me the place I am unsuitable, what I am doing unsuitable. Or may this be a server facet error?

Code for rtmp class:

import AVFoundation
import HaishinKit

class RTMP: ObservableObject {
    
    non-public let audioSession: AVAudioSession
    
    non-public var connection: RTMPConnection?
    non-public var rtmpStream: RTMPStream!
    non-public var streamName = ""
    non-public var connectTo = ""
    non-public var retryCount: Int = 0
    let maxRetryCount: Int = 5
    
    init() {
        
        self.audioSession = AVAudioSession.sharedInstance()
        if audioSession.recordPermission != .granted {
            audioSession.requestRecordPermission { (isGranted) in
                if !isGranted {
                    fatalError("Entry denied")
                }
            }
        }
        
        do {
            strive audioSession.setCategory(.playAndRecord, mode: .default, choices: [])
            strive audioSession.setActive(true)
        } catch {
            fatalError(error.localizedDescription)
        }
    }
    
    func startStream(streamName: String?, connectTo: String?) {
        guard let stream = streamName,
              let join = connectTo else {
            print("Invalid streamName, invalid connection")
            return
        }
        self.streamName = stream
        self.connectTo = join
        
        connection = RTMPConnection()
        rtmpStream = RTMPStream(connection: connection!)
        connection?.addEventListener(.rtmpStatus, selector: #selector(rtmpStatusHandler), observer: self)
        connection?.addEventListener(.ioError, selector: #selector(rtmpErrorHandler), observer: self)
        
        rtmpStream.attachAudio(AVCaptureDevice.default(for: .audio)) { error in
            print("attachAudio (error)")
        }
//        connection?.requireNetworkFramework = true
        connection?.join(join)
    }

    func stopPublish(completion: @escaping () -> ()) {
        rtmpStream.shut()
        connection?.shut()
        connection?.removeEventListener(.rtmpStatus, selector: #selector(rtmpStatusHandler), observer: self)
        connection?.removeEventListener(.ioError, selector: #selector(rtmpErrorHandler), observer: self)
        connection = nil
        completion()
    }
    
    func pausePublish() {
        rtmpStream.paused.toggle()
    }
    
    @objc
    non-public func rtmpStatusHandler(_ notification: Notification) {
        let e = Occasion.from(notification)
        guard let knowledge: ASObject = e.knowledge as? ASObject, let code: String = knowledge["code"] as? String else {
            return
        }
        print(code)
        change code {
        case RTMPConnection.Code.connectSuccess.rawValue:
            retryCount = 0
            rtmpStream.publish(streamName)
        case RTMPConnection.Code.connectFailed.rawValue, RTMPConnection.Code.connectClosed.rawValue:
            guard retryCount <= maxRetryCount else {
                return
            }
            Thread.sleep(forTimeInterval: pow(2.0, Double(retryCount)))
            connection?.join(connectTo)
            retryCount += 1
            
        default:
            break
        }
    }
    
    @objc
    non-public func rtmpErrorHandler(_ notification: Notification) {
        let e = Occasion.from(notification)
        guard let knowledge: ASObject = e.knowledge as? ASObject, let code: String = knowledge["level"] as? String, let description: String = knowledge["description"] as? String else {
            return
        }
        print("rtmpErrorHandler: (code)")
        print("rtmpErrorHandler description: (description)")
        connection?.join(connectTo)
    }
}

code for reconnection:

struct TestView: View {
    @EnvironmentObject non-public var configLanguage: LanguageConfig
    @EnvironmentObject var rtmp: RTMP
    @EnvironmentObject var websocket: Websocket
    @EnvironmentObject var community: Community
    
    @State non-public var switchLanguage: Bool = false
    
    var physique: some View {
        ZStack {
            Button(motion: {
                print("change language")
                switchLanguage.toggle()
            }, label: {
                Textual content(configLanguage.language.rawValue)
            })
        }
        .sheet(isPresented: $switchLanguage) {
            if configLanguage.isChanged {
                websocket.disconnect()
                rtmp.stopPublish(completion: {
                    community.postRequest(language: configLanguage.language, completion: { mannequin in
                        websocket.join(with: mannequin.read_url, completion: {
                            rtmp.startStream(streamName: mannequin.stream_name, connectTo: mannequin.ingestion_url)
                            
                        })
                    })
                })
            }
        } content material: {
            SwitchLanguageView()
                .presentationDetents([.large])
                .presentationDragIndicator(.seen)
        }
    }
}

code for websocket connection:

func join(with: String?, completion: @escaping () -> ()) {
        
        guard let string = with else {
            print("Invalid string to attach websocket")
            return
        }
        
        guard let url = URL(string: string) else { return }
        let request = URLRequest(url: url)
        webSocketTask = URLSession.shared.webSocketTask(with: request)
        webSocketTask?.resume()
        receiveMessage()
        completion()
    }

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments