From 6c3beae3198296e6675e6097ba54151ac68b2f98 Mon Sep 17 00:00:00 2001 From: Chen-Alexander <1401429109@qq.com> Date: Mon, 24 Aug 2020 15:06:13 +0800 Subject: [PATCH 1/3] 1:add transCoding function. Former-commit-id: c92ef35a577f9765d59d63a1fc51f71c09ca8728 --- .../examples/advanced/RTMPStreaming.java | 179 +++++++++--------- .../res/layout/fragment_rtmp_streaming.xml | 26 +++ 2 files changed, 113 insertions(+), 92 deletions(-) diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java index 1135baa37..d9d8273e5 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java @@ -9,8 +9,11 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.CompoundButton; import android.widget.EditText; import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.Switch; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -26,6 +29,7 @@ import io.agora.rtc.IRtcEngineEventHandler; import io.agora.rtc.RtcEngine; import io.agora.rtc.live.LiveTranscoding; +import io.agora.rtc.video.AgoraImage; import io.agora.rtc.video.VideoCanvas; import io.agora.rtc.video.VideoEncoderConfiguration; @@ -36,11 +40,13 @@ import static io.agora.rtc.video.VideoEncoderConfiguration.STANDARD_BITRATE; import static io.agora.rtc.video.VideoEncoderConfiguration.VD_640x360; -/**This example demonstrates how to push a stream to an external address. - * +/** + * This example demonstrates how to push a stream to an external address. + *

* Important: - * Users who push and pull streams cannot be in one channel, - * otherwise unexpected errors will occur.*/ + * Users who push and pull streams cannot be in one channel, + * otherwise unexpected errors will occur. + */ @Example( index = 3, group = ADVANCED, @@ -48,29 +54,37 @@ actionId = R.id.action_mainFragment_to_RTMPStreaming, tipsId = R.string.rtmpstreaming ) -public class RTMPStreaming extends BaseFragment implements View.OnClickListener -{ +public class RTMPStreaming extends BaseFragment implements View.OnClickListener { private static final String TAG = RTMPStreaming.class.getSimpleName(); + private LinearLayout llTransCode; + private Switch transCodeSwitch; private FrameLayout fl_local, fl_remote; private EditText et_url, et_channel; private Button join, publish; private RtcEngine engine; private int myUid; private boolean joined = false, publishing = false; + private VideoEncoderConfiguration.VideoDimensions dimensions = VD_640x360; + private LiveTranscoding transcoding = new LiveTranscoding(); + /** + * Maximum number of users participating in transcoding (even number) + */ + private final int MAXUserCount = 2; + private LiveTranscoding.TranscodingUser localTranscodingUser; @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) - { + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_rtmp_streaming, container, false); return view; } @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) - { + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); + llTransCode = view.findViewById(R.id.ll_TransCode); + transCodeSwitch = view.findViewById(R.id.transCode_Switch); fl_local = view.findViewById(R.id.fl_local); fl_remote = view.findViewById(R.id.fl_remote); et_channel = view.findViewById(R.id.et_channel); @@ -82,17 +96,14 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat } @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) - { + public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Check if the context is valid Context context = getContext(); - if (context == null) - { + if (context == null) { return; } - try - { + try { /**Creates an RtcEngine instance. * @param context The context of Android Activity * @param appId The App ID issued to you by Agora. See @@ -101,20 +112,17 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) * The SDK uses this class to report to the app on SDK runtime events.*/ engine = RtcEngine.create(context.getApplicationContext(), getString(R.string.agora_app_id), iRtcEngineEventHandler); } - catch (Exception e) - { + catch (Exception e) { e.printStackTrace(); getActivity().onBackPressed(); } } @Override - public void onDestroy() - { + public void onDestroy() { super.onDestroy(); /**leaveChannel and Destroy the RtcEngine instance*/ - if(engine != null) - { + if (engine != null) { engine.leaveChannel(); } handler.post(RtcEngine::destroy); @@ -122,19 +130,15 @@ public void onDestroy() } @Override - public void onClick(View v) - { + public void onClick(View v) { - if (v.getId() == R.id.btn_join) - { - if(!joined) - { + if (v.getId() == R.id.btn_join) { + if (!joined) { CommonUtil.hideInputBoard(getActivity(), et_channel); // call when join button hit String channelId = et_channel.getText().toString(); // Check permission - if (AndPermission.hasPermissions(this, Permission.Group.STORAGE, Permission.Group.MICROPHONE, Permission.Group.CAMERA)) - { + if (AndPermission.hasPermissions(this, Permission.Group.STORAGE, Permission.Group.MICROPHONE, Permission.Group.CAMERA)) { joinChannel(channelId); return; } @@ -148,37 +152,29 @@ public void onClick(View v) // Permissions Granted joinChannel(channelId); }).start(); - } - else - { + } else { engine.leaveChannel(); + transCodeSwitch.setEnabled(true); joined = false; join.setText(getString(R.string.join)); publishing = false; publish.setEnabled(false); publish.setText(getString(R.string.publish)); } - } - else if (v.getId() == R.id.btn_publish) - { + } else if (v.getId() == R.id.btn_publish) { /**Ensure that the user joins a channel before calling this method.*/ - if(joined && !publishing) - { + if (joined && !publishing) { startPublish(); - } - else if(joined && publishing) - { + } else if (joined && publishing) { stopPublish(); } } } - private void joinChannel(String channelId) - { + private void joinChannel(String channelId) { // Check if the context is valid Context context = getContext(); - if (context == null) - { + if (context == null) { return; } @@ -206,7 +202,7 @@ private void joinChannel(String channelId) engine.enableVideo(); // Setup video encoding configs engine.setVideoEncoderConfiguration(new VideoEncoderConfiguration( - VD_640x360, + dimensions, FRAME_RATE_FPS_15, STANDARD_BITRATE, ORIENTATION_MODE_ADAPTIVE @@ -221,15 +217,13 @@ private void joinChannel(String channelId) * A token generated at the server. This applies to scenarios with high-security requirements. For details, see * https://docs.agora.io/en/cloud-recording/token_server_java?platform=Java*/ String accessToken = getString(R.string.agora_access_token); - if (TextUtils.equals(accessToken, "") || TextUtils.equals(accessToken, "<#YOUR ACCESS TOKEN#>")) - { + if (TextUtils.equals(accessToken, "") || TextUtils.equals(accessToken, "<#YOUR ACCESS TOKEN#>")) { accessToken = null; } /** Allows a user to join a channel. if you do not specify the uid, we will generate the uid for you*/ int res = engine.joinChannel(accessToken, channelId, "Extra Optional Data", 0); - if (res != 0) - { + if (res != 0) { // Usually happens with invalid parameters // Error code description can be found at: // en: https://docs.agora.io/en/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_error_code.html @@ -241,23 +235,26 @@ private void joinChannel(String channelId) join.setEnabled(false); } - private void startPublish() - { + private void startPublish() { /**LiveTranscoding: A class for managing user-specific CDN live audio/video transcoding settings. * See */ - LiveTranscoding transcoding = new LiveTranscoding(); + transcoding.width = dimensions.height; + transcoding.height = dimensions.width; + transcoding.backgroundColor = getResources().getColor(R.color.colorAccent); /**The transcodingUser class which defines the video properties of the user displaying the * video in the CDN live. Agora supports a maximum of 17 transcoding users in a CDN live streaming channel. * See */ - LiveTranscoding.TranscodingUser transcodingUser = new LiveTranscoding.TranscodingUser(); - transcodingUser.width = transcoding.width; - transcodingUser.height = transcoding.height; - transcodingUser.uid = myUid; + localTranscodingUser = new LiveTranscoding.TranscodingUser(); + localTranscodingUser.x = 0; + localTranscodingUser.y = 0; + localTranscodingUser.width = transcoding.width; + localTranscodingUser.height = transcoding.height / MAXUserCount; + localTranscodingUser.uid = myUid; /**Adds a user displaying the video in CDN live. * @return * 0: Success. * <0: Failure.*/ - int ret = transcoding.addUser(transcodingUser); + int ret = transcoding.addUser(localTranscodingUser); /**Sets the video layout and audio settings for CDN live. * The SDK triggers the onTranscodingUpdated callback when you call this method to update * the LiveTranscodingclass. If you call this method to set the LiveTranscoding class for @@ -303,8 +300,7 @@ private void startPublish() publish.setEnabled(false); } - private void stopPublish() - { + private void stopPublish() { publishing = false; publish.setEnabled(true); publish.setText(getString(R.string.publish)); @@ -330,21 +326,18 @@ private void stopPublish() * IRtcEngineEventHandler is an abstract class providing default implementation. * The SDK uses this class to report to the app on SDK runtime events. */ - private final IRtcEngineEventHandler iRtcEngineEventHandler = new IRtcEngineEventHandler() - { + private final IRtcEngineEventHandler iRtcEngineEventHandler = new IRtcEngineEventHandler() { /**Reports a warning during SDK runtime. * Warning code: https://docs.agora.io/en/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_warn_code.html*/ @Override - public void onWarning(int warn) - { + public void onWarning(int warn) { Log.w(TAG, String.format("onWarning code %d message %s", warn, RtcEngine.getErrorDescription(warn))); } /**Reports an error during SDK runtime. * Error code: https://docs.agora.io/en/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_error_code.html*/ @Override - public void onError(int err) - { + public void onError(int err) { Log.e(TAG, String.format("onError code %d message %s", err, RtcEngine.getErrorDescription(err))); showAlert(String.format("onError code %d message %s", err, RtcEngine.getErrorDescription(err))); } @@ -353,8 +346,7 @@ public void onError(int err) * @param stats With this callback, the application retrieves the channel information, * such as the call duration and statistics.*/ @Override - public void onLeaveChannel(RtcStats stats) - { + public void onLeaveChannel(RtcStats stats) { super.onLeaveChannel(stats); Log.i(TAG, String.format("local user %d leaveChannel!", myUid)); showLongToast(String.format("local user %d leaveChannel!", myUid)); @@ -367,17 +359,15 @@ public void onLeaveChannel(RtcStats stats) * @param uid User ID * @param elapsed Time elapsed (ms) from the user calling joinChannel until this callback is triggered*/ @Override - public void onJoinChannelSuccess(String channel, int uid, int elapsed) - { + public void onJoinChannelSuccess(String channel, int uid, int elapsed) { Log.i(TAG, String.format("onJoinChannelSuccess channel %s uid %d", channel, uid)); showLongToast(String.format("onJoinChannelSuccess channel %s uid %d", channel, uid)); myUid = uid; joined = true; - handler.post(new Runnable() - { + handler.post(new Runnable() { @Override - public void run() - { + public void run() { + transCodeSwitch.setEnabled(false); join.setEnabled(true); join.setText(getString(R.string.leave)); publish.setEnabled(true); @@ -419,8 +409,7 @@ public void run() * @param elapsed Time elapsed (ms) from the local user calling the joinChannel method * until the SDK triggers this callback.*/ @Override - public void onRemoteAudioStateChanged(int uid, int state, int reason, int elapsed) - { + public void onRemoteAudioStateChanged(int uid, int state, int reason, int elapsed) { super.onRemoteAudioStateChanged(uid, state, reason, elapsed); Log.i(TAG, "onRemoteAudioStateChanged->" + uid + ", state->" + state + ", reason->" + reason); } @@ -463,8 +452,7 @@ public void onRemoteAudioStateChanged(int uid, int state, int reason, int elapse * @param elapsed Time elapsed (ms) from the local user calling the joinChannel method until * the SDK triggers this callback.*/ @Override - public void onRemoteVideoStateChanged(int uid, int state, int reason, int elapsed) - { + public void onRemoteVideoStateChanged(int uid, int state, int reason, int elapsed) { super.onRemoteVideoStateChanged(uid, state, reason, elapsed); Log.i(TAG, "onRemoteVideoStateChanged->" + uid + ", state->" + state + ", reason->" + reason); } @@ -516,19 +504,15 @@ public void onRemoteVideoStateChanged(int uid, int state, int reason, int elapse * RTMP_STREAM_PUBLISH_ERROR_FORMAT_NOT_SUPPORTED(10): The format of the RTMP streaming * URL is not supported. Check whether the URL format is correct.*/ @Override - public void onRtmpStreamingStateChanged(String url, int state, int errCode) - { + public void onRtmpStreamingStateChanged(String url, int state, int errCode) { super.onRtmpStreamingStateChanged(url, state, errCode); Log.i(TAG, "onRtmpStreamingStateChanged->" + url + ", state->" + state + ", errCode->" + errCode); - if(state == Constants.RTMP_STREAM_PUBLISH_STATE_RUNNING) - { + if (state == Constants.RTMP_STREAM_PUBLISH_STATE_RUNNING) { /**After confirming the successful push, make changes to the UI.*/ publishing = true; - handler.post(new Runnable() - { + handler.post(new Runnable() { @Override - public void run() - { + public void run() { publish.setEnabled(true); publish.setText(getString(R.string.stoppublish)); } @@ -541,8 +525,7 @@ public void run() * @param elapsed Time delay (ms) from the local user calling joinChannel/setClientRole * until this callback is triggered.*/ @Override - public void onUserJoined(int uid, int elapsed) - { + public void onUserJoined(int uid, int elapsed) { super.onUserJoined(uid, elapsed); Log.i(TAG, "onUserJoined->" + uid); showLongToast(String.format("user %d joined!", uid)); @@ -556,8 +539,7 @@ public void onUserJoined(int uid, int elapsed) /**Display remote video stream*/ SurfaceView surfaceView = RtcEngine.CreateRendererView(context); surfaceView.setZOrderMediaOverlay(true); - if (fl_remote.getChildCount() > 0) - { + if (fl_remote.getChildCount() > 0) { fl_remote.removeAllViews(); } // Add to the remote container @@ -565,6 +547,20 @@ public void onUserJoined(int uid, int elapsed) // Setup remote video to render engine.setupRemoteVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, uid)); }); + /**Determine whether to open transcoding service and whether the current number of + * transcoding users exceeds the maximum number of users*/ + if (transCodeSwitch.isChecked() && transcoding.getUserCount() < MAXUserCount) { + /**The transcoding images are arranged vertically according to the adding order*/ + LiveTranscoding.TranscodingUser transcodingUser = new LiveTranscoding.TranscodingUser(); + transcodingUser.x = 0; + transcodingUser.y = localTranscodingUser.height; + transcodingUser.width = transcoding.width; + transcodingUser.height = transcoding.height / MAXUserCount; + transcodingUser.uid = uid; + int ret = transcoding.addUser(transcodingUser); + /**refresh transCoding configuration*/ + engine.setLiveTranscoding(transcoding); + } } /**Occurs when a remote user (Communication)/host (Live Broadcast) leaves the channel. @@ -578,8 +574,7 @@ public void onUserJoined(int uid, int elapsed) * USER_OFFLINE_BECOME_AUDIENCE(2): (Live broadcast only.) The client role switched from * the host to the audience.*/ @Override - public void onUserOffline(int uid, int reason) - { + public void onUserOffline(int uid, int reason) { Log.i(TAG, String.format("user %d offline! reason:%d", uid, reason)); showLongToast(String.format("user %d offline! reason:%d", uid, reason)); handler.post(new Runnable() { diff --git a/Android/APIExample/app/src/main/res/layout/fragment_rtmp_streaming.xml b/Android/APIExample/app/src/main/res/layout/fragment_rtmp_streaming.xml index 1ebe2ce5b..ead5d3921 100644 --- a/Android/APIExample/app/src/main/res/layout/fragment_rtmp_streaming.xml +++ b/Android/APIExample/app/src/main/res/layout/fragment_rtmp_streaming.xml @@ -24,6 +24,32 @@ android:layout_alignParentTop="true" android:layout_alignParentEnd="true" /> + + + + + + + + Date: Mon, 24 Aug 2020 15:35:44 +0800 Subject: [PATCH 2/3] 1:add transCoding function. 2:organized code. Former-commit-id: 1603d8f0c6c8c419a0af70409fda91525189e2ad --- .../examples/advanced/RTMPStreaming.java | 73 ++++++++++--------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java index d9d8273e5..7e810a3ff 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java @@ -236,41 +236,42 @@ private void joinChannel(String channelId) { } private void startPublish() { - /**LiveTranscoding: A class for managing user-specific CDN live audio/video transcoding settings. - * See */ - transcoding.width = dimensions.height; - transcoding.height = dimensions.width; - transcoding.backgroundColor = getResources().getColor(R.color.colorAccent); - /**The transcodingUser class which defines the video properties of the user displaying the - * video in the CDN live. Agora supports a maximum of 17 transcoding users in a CDN live streaming channel. - * See */ - localTranscodingUser = new LiveTranscoding.TranscodingUser(); - localTranscodingUser.x = 0; - localTranscodingUser.y = 0; - localTranscodingUser.width = transcoding.width; - localTranscodingUser.height = transcoding.height / MAXUserCount; - localTranscodingUser.uid = myUid; - /**Adds a user displaying the video in CDN live. - * @return - * 0: Success. - * <0: Failure.*/ - int ret = transcoding.addUser(localTranscodingUser); - /**Sets the video layout and audio settings for CDN live. - * The SDK triggers the onTranscodingUpdated callback when you call this method to update - * the LiveTranscodingclass. If you call this method to set the LiveTranscoding class for - * the first time, the SDK does not trigger the onTranscodingUpdated callback. - * @param transcoding Sets the CDN live audio/video transcoding settings See - * - * @return - * 0: Success. - * <0: Failure. - * PS: - * This method applies to Live Broadcast only. - * Ensure that you enable the RTMP Converter service before using this function. See - * Prerequisites in Push Streams to CDN. - * Ensure that you call the setClientRole method and set the user role as the host. - * Ensure that you call the setLiveTranscoding method before calling the addPublishStreamUrl method.*/ - engine.setLiveTranscoding(transcoding); + if (transCodeSwitch.isChecked()) { + /**LiveTranscoding: A class for managing user-specific CDN live audio/video transcoding settings. + * See */ + transcoding.width = dimensions.height; + transcoding.height = dimensions.width; + /**The transcodingUser class which defines the video properties of the user displaying the + * video in the CDN live. Agora supports a maximum of 17 transcoding users in a CDN live streaming channel. + * See */ + localTranscodingUser = new LiveTranscoding.TranscodingUser(); + localTranscodingUser.x = 0; + localTranscodingUser.y = 0; + localTranscodingUser.width = transcoding.width; + localTranscodingUser.height = transcoding.height / MAXUserCount; + localTranscodingUser.uid = myUid; + /**Adds a user displaying the video in CDN live. + * @return + * 0: Success. + * <0: Failure.*/ + int ret = transcoding.addUser(localTranscodingUser); + /**Sets the video layout and audio settings for CDN live. + * The SDK triggers the onTranscodingUpdated callback when you call this method to update + * the LiveTranscodingclass. If you call this method to set the LiveTranscoding class for + * the first time, the SDK does not trigger the onTranscodingUpdated callback. + * @param transcoding Sets the CDN live audio/video transcoding settings See + * + * @return + * 0: Success. + * <0: Failure. + * PS: + * This method applies to Live Broadcast only. + * Ensure that you enable the RTMP Converter service before using this function. See + * Prerequisites in Push Streams to CDN. + * Ensure that you call the setClientRole method and set the user role as the host. + * Ensure that you call the setLiveTranscoding method before calling the addPublishStreamUrl method.*/ + engine.setLiveTranscoding(transcoding); + } /**Publishes the local stream to the CDN. * The addPublishStreamUrl method call triggers the onRtmpStreamingStateChanged callback on * the local client to report the state of adding a local stream to the CDN. @@ -295,7 +296,7 @@ private void startPublish() { * This method applies to Live Broadcast only. * Ensure that the user joins a channel before calling this method. * This method adds only one stream HTTP/HTTPS URL address each time it is called.*/ - int code = engine.addPublishStreamUrl(et_url.getText().toString(), true); + int code = engine.addPublishStreamUrl(et_url.getText().toString(), transCodeSwitch.isChecked()); /**Prevent repeated entry*/ publish.setEnabled(false); } From 82e2ddeef5f8b46e38b07b2e156c145d6c11764b Mon Sep 17 00:00:00 2001 From: Chen-Alexander <1401429109@qq.com> Date: Mon, 24 Aug 2020 18:49:25 +0800 Subject: [PATCH 3/3] 1:fix bugs. Former-commit-id: 09d53dcb2c47bd127b672ce0a723061b441dfd8e --- .../examples/advanced/RTMPStreaming.java | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java index 7e810a3ff..7d6b2680d 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/RTMPStreaming.java @@ -21,6 +21,7 @@ import com.yanzhenjie.permission.AndPermission; import com.yanzhenjie.permission.runtime.Permission; +import io.agora.api.component.Constant; import io.agora.api.example.R; import io.agora.api.example.annotation.Example; import io.agora.api.example.common.BaseFragment; @@ -66,7 +67,7 @@ public class RTMPStreaming extends BaseFragment implements View.OnClickListener private int myUid; private boolean joined = false, publishing = false; private VideoEncoderConfiguration.VideoDimensions dimensions = VD_640x360; - private LiveTranscoding transcoding = new LiveTranscoding(); + private LiveTranscoding transcoding; /** * Maximum number of users participating in transcoding (even number) */ @@ -177,7 +178,6 @@ private void joinChannel(String channelId) { if (context == null) { return; } - // Create render view by RtcEngine SurfaceView surfaceView = RtcEngine.CreateRendererView(context); // Local video is on the top @@ -239,6 +239,7 @@ private void startPublish() { if (transCodeSwitch.isChecked()) { /**LiveTranscoding: A class for managing user-specific CDN live audio/video transcoding settings. * See */ + transcoding = new LiveTranscoding(); transcoding.width = dimensions.height; transcoding.height = dimensions.width; /**The transcodingUser class which defines the video properties of the user displaying the @@ -299,12 +300,11 @@ private void startPublish() { int code = engine.addPublishStreamUrl(et_url.getText().toString(), transCodeSwitch.isChecked()); /**Prevent repeated entry*/ publish.setEnabled(false); + /**Prevent duplicate clicks*/ + transCodeSwitch.setEnabled(false); } private void stopPublish() { - publishing = false; - publish.setEnabled(true); - publish.setText(getString(R.string.publish)); /**Removes an RTMP stream from the CDN. * This method removes the RTMP URL address (added by addPublishStreamUrl) from a CDN live * stream. The SDK reports the result of this method call in the onRtmpStreamingStateChanged callback. @@ -368,7 +368,6 @@ public void onJoinChannelSuccess(String channel, int uid, int elapsed) { handler.post(new Runnable() { @Override public void run() { - transCodeSwitch.setEnabled(false); join.setEnabled(true); join.setText(getString(R.string.leave)); publish.setEnabled(true); @@ -511,12 +510,27 @@ public void onRtmpStreamingStateChanged(String url, int state, int errCode) { if (state == Constants.RTMP_STREAM_PUBLISH_STATE_RUNNING) { /**After confirming the successful push, make changes to the UI.*/ publishing = true; - handler.post(new Runnable() { - @Override - public void run() { - publish.setEnabled(true); - publish.setText(getString(R.string.stoppublish)); - } + handler.post(() -> { + publish.setEnabled(true); + publish.setText(getString(R.string.stoppublish)); + }); + } else if (state == Constants.RTMP_STREAM_PUBLISH_STATE_FAILURE) { + /**if failed, make changes to the UI.*/ + publishing = true; + handler.post(() -> { + publish.setEnabled(true); + publish.setText(getString(R.string.publish)); + transCodeSwitch.setEnabled(true); + publishing = false; + }); + } else if (state == Constants.RTMP_STREAM_PUBLISH_STATE_IDLE) { + /**Push stream not started or ended, make changes to the UI.*/ + publishing = true; + handler.post(() -> { + publish.setEnabled(true); + publish.setText(getString(R.string.publish)); + transCodeSwitch.setEnabled(true); + publishing = false; }); } } @@ -585,6 +599,17 @@ public void run() { Note: The video will stay at its last frame, to completely remove it you will need to remove the SurfaceView from its parent*/ engine.setupRemoteVideo(new VideoCanvas(null, RENDER_MODE_HIDDEN, uid)); + if(transcoding != null) { + /**Removes a user from CDN live. + * @return + * 0: Success. + * < 0: Failure.*/ + int code = transcoding.removeUser(uid); + if (code == Constants.ERR_OK) { + /**refresh transCoding configuration*/ + engine.setLiveTranscoding(transcoding); + } + } } }); }