begeekmyfriend / yasea

RTMP live streaming client for Android
MIT License
4.87k stars 1.32k forks source link

NetStream.Publish.BadName code after connection lost #402

Open davidNode8 opened 7 years ago

davidNode8 commented 7 years ago

I've set the application to call the srsPublisher.stopPublish(); method whenever the internet connection is lost. I called the stopPublish method on onRtmpSocketException listener. But, whenever I'm trying to reconnect, this code String code = ((AmfString) ((AmfObject) invoke.getData().get(1)).getProperty("code")).getValue(); on RtmpConnection class will return NetStream.Publish.BadName instead of NetStream.Publish.Start. How should I handle this?

begeekmyfriend commented 7 years ago

Did you set the right URL or have the permission?

davidNode8 commented 7 years ago

Yes, I'm using the same URL as the first time I connect before the connection lost. When I connect for the first time, the code returns NetStream.Publish.Start.

begeekmyfriend commented 7 years ago

Did it happen every time?

davidNode8 commented 7 years ago

Yes, so here's the chronology :

  1. I start publish to RTMP server for the first time, the code returns NetStream.Publish.Start and it connected.
  2. The internet connection lost, then the onRtmpSocketException is called and I call the stopPublish method.
  3. After the connection is back, I call the startPublish method again using the same URL as the previous one before the connection lost
  4. This time, the code always return NetStream.Publish.BadName

I'm wondering if that's the right way to handle internet connection lost in the middle of streaming.

begeekmyfriend commented 7 years ago

What server or host did you connect?

davidNode8 commented 7 years ago

arut ngix RTMP Also, it can reconnect just fine when disconnected manually. The error just happen when it disconnected while the internet connection is lost.

davidNode8 commented 7 years ago

No, the media server is handled by another team, so I can't change it.

begeekmyfriend commented 7 years ago

For nginx-rtmp, the app name should be specified in the configuration file.

rtmp {
    server {
        listen 1935;

        application mytv {
            live on;
        }
    }
}

Then you have to set your url as rtmp://host:1935/mytv/sssssss

kenanchristian commented 7 years ago

Hi, @begeekmyfriend I'm the one who handles the media server. This is the current config file

rtmp {
    server {
        listen 1935;
        chunk_size 4000;

        application hls {
            live on;
            hls on;

            hls_path /data/hls;

            record_append on;

            record all;
            record_path /peeqr;

            exec_publish curl -X POST -d 'video=$name' 'http://localhost:8080/api/watcher';
            exec_publish_done curl -X DELETE -d 'video=$name' 'http://localhost:8080/api/watcher';

            exec_record_done /convert.sh $path $dirname $basename;

            allow publish all;
            allow play all;
        }

    }
}

Anything I missed?

davidNode8 commented 7 years ago

Also, previously the application will crash in this line on RtmpConnection class when the internet connection is lost while streaming

try {
                //I added if (socket != null) here
                socket.close();
                Log.d(TAG, "socket closed");
            } catch (IOException ex) {
                Log.e(TAG, "shutdown(): failed to close socket", ex);
            }
begeekmyfriend commented 7 years ago

Then the url should be set as rtmp://host:1935/hls/ssss.

By the way, you may use FFmpeg command line to verify it by typing

ffmpeg -re -i test.mp4 -vcodec libx264 -acodec libfaac -f flv rtmp://host:1935/hls/ssss

begeekmyfriend commented 7 years ago

@kenanchristian you can reconfig your configuration file as a simple example to check if it is OK as follows

rtmp {
    server {
        listen 1935;

        application mytv {
            live on;
        }
    }
}
kenanchristian commented 7 years ago

@begeekmyfriend Yes, actually it's should be OK. I've tested it using ffmpeg 👍

After reading this thread, the problem only occurs when the app trying to RECONNECT automatically when the internet connection is bad, but it's going well when connecting for the FIRST time or when RECONNECT manually (pause).

begeekmyfriend commented 7 years ago

It seems your server configuration that would respond NetStream.Publish.BadName packet to the client when the stream is occupied but Yasea never produces this packet itself.

begeekmyfriend commented 7 years ago

@davidNode8 the handler on connection exception is here

davidNode8 commented 7 years ago

Yeah. I called stopPublish() method on onRtmpSocketException listener.

kenanchristian commented 7 years ago

@begeekmyfriend Fixed the problem by adding drop_idle_publisher directive to the media server config. So each time there' no data send, the name will be released so it can be used when connecting again

begeekmyfriend commented 7 years ago

It seems that we find some new 'feature' on nginx-rtmp.