RootEncoder icon indicating copy to clipboard operation
RootEncoder copied to clipboard

Stream video through rtmpClient not showing video

Open KingArmstring opened this issue 9 months ago • 8 comments

This is 100% my fault but I really can't figure it out. I am sorry for bothering. I have textureView with opengl, I am drawing frames on surfaces, and made my own encoder, got frames h246 out of it and tried sendVideo, make sure to send the sps and pps first, did not work. I did not send audio, so not sure if that is the reason but I set onlyVideo to true.

I tried the built in VideoEncoder, got frames out of it, use sendVideo and send it, it logs: wrote Video packet, size 11424 but I still can't see anything on either youtuber or fb. I can use your app to see video on them as long as video. I can't use the example provided because I want to be able to handle the shaders.

I am extremely sorry to ask that question as it is my fault but I can't really figure it out.

I tried to find like a steps to follow in the open issues but I couldn't. Please feel free to ignore my question if you are busy. Thanks in advance.

KingArmstring avatar Mar 16 '25 03:03 KingArmstring

Hello,

First of all, YouTube and Facebook need audio to work. If you only send video you will need send audio too. No matter if the audio is a buffer of all 0 (silence) but the audio track is necessary.

About handle shaders, I'm not sure about your requirements but you can create a custom filter that allow you control the shader as you want

pedroSG94 avatar Mar 16 '25 08:03 pedroSG94

Many thanks for replying!

I realised that audio is necessary when I got your example running, everytime I remove sendAudio, I get no video. I tried sending 0 buffer(ByteBuffer.wrap(0)), it did not work, not even crashing or showing any errors like in video when I missed setting the sps and pps, I got some errors logged when enabling logging in rtmpClient, I did not know how to use the encoder you provided so I wrote mine and it is getting audio frames(or sizes around 300bytes per frame) but can't even see any error in logs, so I know why streaming is not working now, it is because I can't send audio. I made sure to rtmpClient.setAudioInfo(44100, true) once before sending anything.

To recape, rtmpClient.sendAudio(buf, bufInfo) is not showing neither error nor success, I get conection message "connected" tho burt surely no audio is being sent.

KingArmstring avatar Mar 17 '25 01:03 KingArmstring

Wait, I got something, now I am seeing logs saying wrote audio and video, youtube senses my presenes but it shows a black screen. Should be easy to fix(hopefully :D) I mean don't reply to me for the moment, don't want to waste ur time. Again can't find words to thank you for both your effort in the lib and your lovely support.

Btw, the issue was so funny, I left setOnlyVideo enabled :V

KingArmstring avatar Mar 17 '25 01:03 KingArmstring

Sorry for being late on replying I had a busy week and I was not working on this as it is my personal project. So as I said last time I was able to see video as a black screen which was a big step forward, today I fixed that, I just needed to fix my encoder and it worked immediately. I am really thankful for your answer :)

I have a question but feel free to close it for me if you think I should open a new issue. When connecting to facebook, it works fine now, but when I change something in the code then restart, it does not work and gives this error:

java.io.EOFException: Not enough data available at io.ktor.utils.io.ByteReadChannelOperationsKt.readByte(ByteReadChannelOperations.kt:48) at io.ktor.utils.io.ByteReadChannelOperationsKt$readByte$1.invokeSuspend(Unknown Source:13) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)

If I wait like some minutes, it works again. If I am on YouTube, it just works when restarting the app immediately. If you can't help like your are busy, we all are, so please feel free to just ignore my question if you want to, all thanks for the previous help.

KingArmstring avatar Mar 22 '25 22:03 KingArmstring

Hello,

What do you means with change something in the code? Are you using rtmp in both cases or rtmps for Facebook and rtmp for YouTube?. Maybe it is related with that. Since the error is in ktor, a possibe solution is use java.io sockets instead of ktor sockets:

genericStream.getStreamClient().setSocketType(SocketType.JAVA)

If you are using RtmpClient it is exactly the same:

rtmpClient.setSocketType(SocketType.JAVA)

Of course, you need call it before startStream

pedroSG94 avatar Mar 22 '25 22:03 pedroSG94

I did not mean anything specific, I was just mentioning the reason why I restarted the stream like for example, changing the UI or anything else not relevant to streaming. Even if I don't change anything then restart the stream, it won't work.

Here is the client I am using:

private val rtmpClient = RtmpClient(
        object : ConnectChecker{
            override fun onAuthError() {
                Timber.d("$CAMERA_TAG: fn onAuthError")
            }

            override fun onAuthSuccess() {
                Timber.d("$CAMERA_TAG: fn onAuthSuccess")
            }

            override fun onConnectionFailed(reason: String) {
                Timber.d("$CAMERA_TAG: fn onConnectionFailed")
            }

            override fun onConnectionStarted(url: String) {
                Timber.d("$CAMERA_TAG: fn onConnectionStarted")
            }

            override fun onConnectionSuccess() {
                Timber.d("$CAMERA_TAG: fn onConnectionSuccess")
            }

            override fun onDisconnect() {
                Timber.d("$CAMERA_TAG: fn onDisconnect")
            }
        }
    )

then calling sendVideo on that and feed it with my h264 encoded frames.

Here is my code for feeding the client(onOutputBufferAvailable):

override fun onOutputBufferAvailable(codec: MediaCodec, index: Int, info: BufferInfo) {
                val outputBuffer: ByteBuffer? = codec.getOutputBuffer(index)

                val outData = ByteArray(outputBuffer!!.remaining())
                outputBuffer[outData, 0, outData.size]
                outputBuffer.rewind()
                setSpsAndPpsAndVps(outputBuffer, info, rtmpClient)
                rtmpClient.sendVideo(ByteBuffer.wrap(outData), info)
                codec.releaseOutputBuffer(index, false)
            }

Unfortunately the client I am using does not let me use java.io instead of ktor

KingArmstring avatar Mar 22 '25 22:03 KingArmstring

Something weird happened, this error never happens when working on YouTube, just happens on Facebook and only happens if I restart the stream immediately, so if I wait like half a minute or so, it does not happen.

KingArmstring avatar Apr 01 '25 06:04 KingArmstring

It is maybe related with TLS of ktor, did you test using java socket or library version 2.5.2? Library version 2.5.2 use a ktor version more stable for TLS, I reverted the ktor version for the next release due to TLS problems

pedroSG94 avatar Apr 01 '25 11:04 pedroSG94