From 026bf054300ac476cea263100e6e91fbec5967aa Mon Sep 17 00:00:00 2001 From: xianing Date: Wed, 1 Dec 2021 18:41:20 +0800 Subject: [PATCH 01/13] add face beauty, update rtmp streaming api usage --- .../io/agora/api/example/ExampleActivity.java | 4 + .../example/examples/advanced/FaceBeauty.java | 466 ++++++++++++++++++ .../examples/advanced/RTMPStreaming.java | 173 +++---- .../res/layout/fragment_rtmp_streaming.xml | 2 +- .../res/layout/fragment_video_enhancement.xml | 184 +++++++ .../app/src/main/res/navigation/nav_graph.xml | 24 +- .../app/src/main/res/values-zh/strings.xml | 15 + .../app/src/main/res/values/strings.xml | 15 + 8 files changed, 749 insertions(+), 134 deletions(-) create mode 100644 Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/FaceBeauty.java create mode 100644 Android/APIExample/app/src/main/res/layout/fragment_video_enhancement.xml diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/ExampleActivity.java b/Android/APIExample/app/src/main/java/io/agora/api/example/ExampleActivity.java index 7c51e7e4c..3d4907049 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/ExampleActivity.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/ExampleActivity.java @@ -33,6 +33,7 @@ import io.agora.api.example.examples.advanced.SwitchExternalVideo; import io.agora.api.example.examples.advanced.SetAudioProfile; import io.agora.api.example.examples.advanced.MultiProcess; +import io.agora.api.example.examples.advanced.FaceBeauty; import io.agora.api.example.examples.advanced.VideoQuickSwitch; import io.agora.api.example.examples.advanced.RTMPStreaming; import io.agora.api.example.examples.advanced.StreamEncrypt; @@ -158,6 +159,9 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { case R.id.action_mainFragment_raw_audio: fragment = new ProcessAudioRawData(); break; + case R.id.action_mainFragment_video_enhancement: + fragment = new FaceBeauty(); + break; default: fragment = new JoinChannelAudio(); break; diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/FaceBeauty.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/FaceBeauty.java new file mode 100644 index 000000000..302ea8775 --- /dev/null +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/FaceBeauty.java @@ -0,0 +1,466 @@ +package io.agora.api.example.examples.advanced; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.SurfaceView; +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.SeekBar; +import android.widget.Switch; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.yanzhenjie.permission.AndPermission; +import com.yanzhenjie.permission.runtime.Permission; + +import io.agora.api.example.MainApplication; +import io.agora.api.example.R; +import io.agora.api.example.annotation.Example; +import io.agora.api.example.common.BaseFragment; +import io.agora.api.example.utils.CommonUtil; +import io.agora.rtc.IRtcEngineEventHandler; +import io.agora.rtc.RtcEngine; +import io.agora.rtc.RtcEngineConfig; +import io.agora.rtc.models.ChannelMediaOptions; +import io.agora.rtc.video.BeautyOptions; +import io.agora.rtc.video.VideoCanvas; +import io.agora.rtc.video.VideoEncoderConfiguration; + +import static io.agora.api.example.common.model.Examples.ADVANCED; +import static io.agora.rtc.Constants.CHANNEL_PROFILE_LIVE_BROADCASTING; +import static io.agora.rtc.Constants.RENDER_MODE_HIDDEN; +import static io.agora.rtc.video.VideoEncoderConfiguration.STANDARD_BITRATE; + +/** + * This demo demonstrates how to make a VideoProcessExtension + */ +@Example( + index = 28, + group = ADVANCED, + name = R.string.item_videoProcessExtension, + actionId = R.id.action_mainFragment_video_enhancement, + tipsId = R.string.videoEnhancement +) +public class FaceBeauty extends BaseFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener, SeekBar.OnSeekBarChangeListener { + private static final String TAG = FaceBeauty.class.getSimpleName(); + + private FrameLayout fl_local, fl_remote; + private LinearLayout controlPanel; + private Button join; + private Switch beauty; + private SeekBar seek_lightness, seek_redness, seek_sharpness, seek_smoothness; + private EditText et_channel; + private RtcEngine engine; + private int myUid; + private boolean joined = false; + private BeautyOptions beautyOptions = new BeautyOptions(); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) + { + View view = inflater.inflate(R.layout.fragment_video_enhancement, container, false); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) + { + super.onViewCreated(view, savedInstanceState); + join = view.findViewById(R.id.btn_join); + join.setOnClickListener(this); + et_channel = view.findViewById(R.id.et_channel); + fl_local = view.findViewById(R.id.fl_local); + fl_remote = view.findViewById(R.id.fl_remote); + controlPanel = view.findViewById(R.id.controlPanel); + beauty = view.findViewById(R.id.switch_face_beautify); + beauty.setOnCheckedChangeListener(this); + seek_lightness = view.findViewById(R.id.lightening); + seek_lightness.setOnSeekBarChangeListener(this); + seek_redness = view.findViewById(R.id.redness); + seek_redness.setOnSeekBarChangeListener(this); + seek_sharpness = view.findViewById(R.id.sharpness); + seek_sharpness.setOnSeekBarChangeListener(this); + seek_smoothness = view.findViewById(R.id.smoothness); + seek_smoothness.setOnSeekBarChangeListener(this); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) + { + super.onActivityCreated(savedInstanceState); + // Check if the context is valid + Context context = getContext(); + if (context == null) + { + return; + } + try + { + RtcEngineConfig config = new RtcEngineConfig(); + /** + * The context of Android Activity + */ + config.mContext = context.getApplicationContext(); + /** + * The App ID issued to you by Agora. See How to get the App ID + */ + config.mAppId = getString(R.string.agora_app_id); + /** + * IRtcEngineEventHandler is an abstract class providing default implementation. + * The SDK uses this class to report to the app on SDK runtime events. + */ + config.mEventHandler = iRtcEngineEventHandler; + engine = RtcEngine.create(config); + engine.setChannelProfile(CHANNEL_PROFILE_LIVE_BROADCASTING); + } + catch (Exception e) + { + e.printStackTrace(); + getActivity().onBackPressed(); + } + } + + @Override + public void onDestroy() + { + super.onDestroy(); + /**leaveChannel and Destroy the RtcEngine instance*/ + if(engine != null) + { + engine.leaveChannel(); + engine.stopPreview(); + } + handler.post(RtcEngine::destroy); + engine = null; + } + + + + private void joinChannel(String channelId) + { + // Check if the context is valid + Context context = getContext(); + if (context == null) + { + return; + } + + // Create render view by RtcEngine + SurfaceView surfaceView = RtcEngine.CreateRendererView(context); + if(fl_local.getChildCount() > 0) + { + fl_local.removeAllViews(); + } + // Add to the local container + fl_local.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + // Setup local video to render your local camera preview + engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); + // Set audio route to microPhone + engine.setDefaultAudioRoutetoSpeakerphone(true); + + /**In the demo, the default is to enter as the anchor.*/ + engine.setClientRole(IRtcEngineEventHandler.ClientRole.CLIENT_ROLE_BROADCASTER); + // Enable video module + engine.enableVideo(); + // Setup video encoding configs + engine.setVideoEncoderConfiguration(new VideoEncoderConfiguration( + ((MainApplication)getActivity().getApplication()).getGlobalSettings().getVideoEncodingDimensionObject(), + VideoEncoderConfiguration.FRAME_RATE.valueOf(((MainApplication)getActivity().getApplication()).getGlobalSettings().getVideoEncodingFrameRate()), + STANDARD_BITRATE, + VideoEncoderConfiguration.ORIENTATION_MODE.valueOf(((MainApplication)getActivity().getApplication()).getGlobalSettings().getVideoEncodingOrientation()) + )); + + /**Please configure accessToken in the string_config file. + * A temporary token generated in Console. A temporary token is valid for 24 hours. For details, see + * https://docs.agora.io/en/Agora%20Platform/token?platform=All%20Platforms#get-a-temporary-token + * 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#>")) + { + accessToken = null; + } + /** + * enable face beauty by default + */ + engine.startPreview(); + /** Allows a user to join a channel. + if you do not specify the uid, we will generate the uid for you*/ + + + ChannelMediaOptions option = new ChannelMediaOptions(); + option.autoSubscribeAudio = true; + option.autoSubscribeVideo = true; + int res = engine.joinChannel(accessToken, channelId, "", 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 + // cn: https://docs.agora.io/cn/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_error_code.html + showAlert(RtcEngine.getErrorDescription(Math.abs(res))); + return; + } + // Prevent repeated entry + join.setEnabled(false); + } + + @Override + public void onClick(View v) { + 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)) + { + joinChannel(channelId); + return; + } + // Request permission + AndPermission.with(this).runtime().permission( + Permission.Group.STORAGE, + Permission.Group.MICROPHONE, + Permission.Group.CAMERA + ).onGranted(permissions -> + { + // Permissions Granted + joinChannel(channelId); + }).start(); + } + else + { + joined = false; + /**After joining a channel, the user must call the leaveChannel method to end the + * call before joining another channel. This method returns 0 if the user leaves the + * channel and releases all resources related to the call. This method call is + * asynchronous, and the user has not exited the channel when the method call returns. + * Once the user leaves the channel, the SDK triggers the onLeaveChannel callback. + * A successful leaveChannel method call triggers the following callbacks: + * 1:The local client: onLeaveChannel. + * 2:The remote client: onUserOffline, if the user leaving the channel is in the + * Communication channel, or is a BROADCASTER in the Live Broadcast profile. + * @returns 0: Success. + * < 0: Failure. + * PS: + * 1:If you call the destroy method immediately after calling the leaveChannel + * method, the leaveChannel process interrupts, and the SDK does not trigger + * the onLeaveChannel callback. + * 2:If you call the leaveChannel method during CDN live streaming, the SDK + * triggers the removeInjectStreamUrl method.*/ + engine.leaveChannel(); + engine.stopPreview(); + join.setText(getString(R.string.join)); + controlPanel.setVisibility(View.INVISIBLE); + } + } + } + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if(buttonView.getId() == beauty.getId()){ + engine.setBeautyEffectOptions(isChecked, beautyOptions); + } + } + + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + float value = ((float) progress) / 10; + if(seekBar.getId() == seek_lightness.getId()){ + beautyOptions.lighteningLevel = value; + engine.setBeautyEffectOptions(beauty.isChecked(), beautyOptions); + } + else if(seekBar.getId() == seek_redness.getId()){ + beautyOptions.rednessLevel = value; + engine.setBeautyEffectOptions(beauty.isChecked(), beautyOptions); + } + else if(seekBar.getId() == seek_sharpness.getId()){ + beautyOptions.sharpnessLevel = value; + engine.setBeautyEffectOptions(beauty.isChecked(), beautyOptions); + } + else if(seekBar.getId() == seek_smoothness.getId()){ + beautyOptions.smoothnessLevel = value; + engine.setBeautyEffectOptions(beauty.isChecked(), beautyOptions); + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + + } + + + /** + * 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() + { + /**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) + { + Log.w(TAG, String.format("onWarning code %d message %s", warn, RtcEngine.getErrorDescription(warn))); + } + + /**Occurs when a user leaves the channel. + * @param stats With this callback, the application retrieves the channel information, + * such as the call duration and statistics.*/ + @Override + 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)); + } + + /**Occurs when the local user joins a specified channel. + * The channel name assignment is based on channelName specified in the joinChannel method. + * If the uid is not specified when joinChannel is called, the server automatically assigns a uid. + * @param channel Channel name + * @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) + { + 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() + { + @Override + public void run() + { + join.setEnabled(true); + join.setText(getString(R.string.leave)); + controlPanel.setVisibility(View.VISIBLE); + } + }); + } + + /**Since v2.9.0. + * Occurs when the remote video state changes. + * PS: This callback does not work properly when the number of users (in the Communication + * profile) or broadcasters (in the Live-broadcast profile) in the channel exceeds 17. + * @param uid ID of the remote user whose video state changes. + * @param state State of the remote video: + * REMOTE_VIDEO_STATE_STOPPED(0): The remote video is in the default state, probably due + * to REMOTE_VIDEO_STATE_REASON_LOCAL_MUTED(3), REMOTE_VIDEO_STATE_REASON_REMOTE_MUTED(5), + * or REMOTE_VIDEO_STATE_REASON_REMOTE_OFFLINE(7). + * REMOTE_VIDEO_STATE_STARTING(1): The first remote video packet is received. + * REMOTE_VIDEO_STATE_DECODING(2): The remote video stream is decoded and plays normally, + * probably due to REMOTE_VIDEO_STATE_REASON_NETWORK_RECOVERY (2), + * REMOTE_VIDEO_STATE_REASON_LOCAL_UNMUTED(4), REMOTE_VIDEO_STATE_REASON_REMOTE_UNMUTED(6), + * or REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK_RECOVERY(9). + * REMOTE_VIDEO_STATE_FROZEN(3): The remote video is frozen, probably due to + * REMOTE_VIDEO_STATE_REASON_NETWORK_CONGESTION(1) or REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK(8). + * REMOTE_VIDEO_STATE_FAILED(4): The remote video fails to start, probably due to + * REMOTE_VIDEO_STATE_REASON_INTERNAL(0). + * @param reason The reason of the remote video state change: + * REMOTE_VIDEO_STATE_REASON_INTERNAL(0): Internal reasons. + * REMOTE_VIDEO_STATE_REASON_NETWORK_CONGESTION(1): Network congestion. + * REMOTE_VIDEO_STATE_REASON_NETWORK_RECOVERY(2): Network recovery. + * REMOTE_VIDEO_STATE_REASON_LOCAL_MUTED(3): The local user stops receiving the remote + * video stream or disables the video module. + * REMOTE_VIDEO_STATE_REASON_LOCAL_UNMUTED(4): The local user resumes receiving the remote + * video stream or enables the video module. + * REMOTE_VIDEO_STATE_REASON_REMOTE_MUTED(5): The remote user stops sending the video + * stream or disables the video module. + * REMOTE_VIDEO_STATE_REASON_REMOTE_UNMUTED(6): The remote user resumes sending the video + * stream or enables the video module. + * REMOTE_VIDEO_STATE_REASON_REMOTE_OFFLINE(7): The remote user leaves the channel. + * REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK(8): The remote media stream falls back to the + * audio-only stream due to poor network conditions. + * REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK_RECOVERY(9): The remote media stream switches + * back to the video stream after the network conditions improve. + * @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) + { + super.onRemoteVideoStateChanged(uid, state, reason, elapsed); + Log.i(TAG, "onRemoteVideoStateChanged->" + uid + ", state->" + state + ", reason->" + reason); + } + + /**Occurs when a remote user (Communication)/host (Live Broadcast) joins the channel. + * @param uid ID of the user whose audio state changes. + * @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) + { + super.onUserJoined(uid, elapsed); + Log.i(TAG, "onUserJoined->" + uid); + showLongToast(String.format("user %d joined!", uid)); + /**Check if the context is correct*/ + Context context = getContext(); + if (context == null) { + return; + } + else{ + handler.post(() -> + { + if(fl_remote.getChildCount() > 0){ + fl_remote.removeAllViews(); + } + /**Display remote video stream*/ + SurfaceView surfaceView = null; + // Create render view by RtcEngine + surfaceView = new SurfaceView(context); + surfaceView.setZOrderMediaOverlay(true); + // Add to the remote container + fl_remote.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + // Setup remote video to render + engine.setupRemoteVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, uid)); + }); + } + } + + /**Occurs when a remote user (Communication)/host (Live Broadcast) leaves the channel. + * @param uid ID of the user whose audio state changes. + * @param reason Reason why the user goes offline: + * USER_OFFLINE_QUIT(0): The user left the current channel. + * USER_OFFLINE_DROPPED(1): The SDK timed out and the user dropped offline because no data + * packet was received within a certain period of time. If a user quits the + * call and the message is not passed to the SDK (due to an unreliable channel), + * the SDK assumes the user dropped offline. + * 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) + { + 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() { + @Override + public void run() { + /**Clear render view + 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)); + } + }); + } + }; +} 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 087918362..78b4e1093 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 @@ -10,7 +10,6 @@ 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; @@ -22,7 +21,6 @@ import com.yanzhenjie.permission.AndPermission; import com.yanzhenjie.permission.runtime.Permission; -import io.agora.api.component.Constant; import io.agora.api.example.MainApplication; import io.agora.api.example.R; import io.agora.api.example.annotation.Example; @@ -33,7 +31,6 @@ import io.agora.rtc.RtcEngine; import io.agora.rtc.live.LiveTranscoding; import io.agora.rtc.models.ChannelMediaOptions; -import io.agora.rtc.video.AgoraImage; import io.agora.rtc.video.VideoCanvas; import io.agora.rtc.video.VideoEncoderConfiguration; @@ -43,9 +40,10 @@ import static io.agora.rtc.Constants.ERR_PUBLISH_STREAM_INTERNAL_SERVER_ERROR; import static io.agora.rtc.Constants.ERR_PUBLISH_STREAM_NOT_FOUND; import static io.agora.rtc.Constants.ERR_TIMEDOUT; +import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_CONNECTION_TIMEOUT; +import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR; +import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_OK; import static io.agora.rtc.video.VideoCanvas.RENDER_MODE_HIDDEN; -import static io.agora.rtc.video.VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15; -import static io.agora.rtc.video.VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_ADAPTIVE; import static io.agora.rtc.video.VideoEncoderConfiguration.STANDARD_BITRATE; import static io.agora.rtc.video.VideoEncoderConfiguration.VD_640x360; @@ -75,7 +73,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; + private LiveTranscoding transcoding = new LiveTranscoding(); private static final Integer MAX_RETRY_TIMES = 3; private int retried = 0; private boolean unpublishing = false; @@ -254,7 +252,6 @@ 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 @@ -271,49 +268,9 @@ private void startPublish() { * 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. - * @param url The CDN streaming URL in the RTMP format. The maximum length of this parameter - * is 1024 bytes. The URL address must not contain special characters, such as - * Chinese language characters. - * @param transcodingEnabled Sets whether transcoding is enabled/disabled. If you set this - * parameter as true, ensure that you call the setLiveTranscoding - * method before this method. - * true: Enable transcoding. To transcode the audio or video - * streams when publishing them to CDN live, often used for - * combining the audio and video streams of multiple hosts in CDN live. - * false: Disable transcoding. - * @return - * 0: Success. - * < 0: Failure. - * ERR_INVALID_ARGUMENT(2): Invalid parameter, usually because the URL address is null or the string length is 0. - * ERR_NOT_INITIALIZED(7): You have not initialized RtcEngine when publishing the stream. - * PS: - * Ensure that you enable the RTMP Converter service before using this function. See - * Prerequisites in Push Streams to CDN. - * 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(), transCodeSwitch.isChecked()); - if(code == 0){ + + if(startRtmpStreaming() == 0){ retryTask = new AsyncTask() { @Override protected Object doInBackground(Object[] objects) { @@ -338,6 +295,17 @@ protected Object doInBackground(Object[] objects) { transCodeSwitch.setEnabled(false); } + private int startRtmpStreaming(){ + int code; + if(transCodeSwitch.isChecked()){ + code = engine.startRtmpStreamWithTranscoding(et_url.getText().toString(), transcoding); + } + else { + code = engine.startRtmpStreamWithoutTranscoding(et_url.getText().toString()); + } + return code; + } + private void stopPublish() { /**Removes an RTMP stream from the CDN. * This method removes the RTMP URL address (added by addPublishStreamUrl) from a CDN live @@ -356,7 +324,7 @@ private void stopPublish() { * This method removes only one stream RTMP URL address each time it is called.*/ unpublishing = true; retryTask.cancel(true); - int ret = engine.removePublishStreamUrl(et_url.getText().toString()); + int ret = engine.stopRtmpStream(et_url.getText().toString()); } /** @@ -517,7 +485,7 @@ public void onRemoteVideoStateChanged(int uid, int state, int reason, int elapse * RTMP_STREAM_PUBLISH_STATE_FAILURE(4): The RTMP streaming fails. See the errCode parameter * for the detailed error information. You can also call the addPublishStreamUrl * method to publish the RTMP streaming again. - * @param errCode The detailed error information for streaming: + * @param errorType The detailed error information for streaming: * RTMP_STREAM_PUBLISH_ERROR_OK(0): The RTMP streaming publishes successfully. * RTMP_STREAM_PUBLISH_ERROR_INVALID_ARGUMEN(1): Invalid argument used. If, for example, * you do not call the setLiveTranscoding method to configure the LiveTranscoding @@ -540,28 +508,44 @@ 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) { - super.onRtmpStreamingStateChanged(url, state, errCode); - Log.i(TAG, "onRtmpStreamingStateChanged->" + url + ", state->" + state + ", errCode->" + errCode); + public void onRtmpStreamingStateChanged(String url, int state, int errorType) { + super.onRtmpStreamingStateChanged(url, state, errorType); + Log.i(TAG, "onRtmpStreamingStateChanged->" + url + ", state->" + state + ", errorType->" + errorType); if (state == Constants.RTMP_STREAM_PUBLISH_STATE_RUNNING) { /**After confirming the successful push, make changes to the UI.*/ - publishing = true; - retryTask.cancel(true); - handler.post(() -> { - publish.setEnabled(true); - publish.setText(getString(R.string.stoppublish)); - }); + if(errorType == RTMP_STREAM_PUBLISH_ERROR_OK){ + publishing = true; + retried = 0; + retryTask.cancel(true); + 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; - retryTask.cancel(true); - handler.post(() -> { - publish.setEnabled(true); - publish.setText(getString(R.string.publish)); - transCodeSwitch.setEnabled(true); - publishing = false; - }); + engine.stopRtmpStream(et_url.getText().toString()); + if((errorType == RTMP_STREAM_PUBLISH_ERROR_CONNECTION_TIMEOUT + || errorType == RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR)) + { + /**if failed, make changes to the UI.*/ + publishing = true; + retryTask.cancel(true); + handler.post(() -> { + publish.setEnabled(true); + publish.setText(getString(R.string.publish)); + transCodeSwitch.setEnabled(true); + publishing = false; + }); + } + else if(url != null && !unpublishing && retried < MAX_RETRY_TIMES + ){ + startRtmpStreaming(); + retried++; + } } else if (state == Constants.RTMP_STREAM_PUBLISH_STATE_IDLE) { + if(unpublishing){ + unpublishing = false; + } /**Push stream not started or ended, make changes to the UI.*/ publishing = true; handler.post(() -> { @@ -573,51 +557,6 @@ public void onRtmpStreamingStateChanged(String url, int state, int errCode) { } } - /** - * Reports the result of calling the removePublishStreamUrl method. - * This callback indicates whether you have successfully removed an RTMP or RTMPS stream from the CDN. - * @param url The CDN streaming URL. - */ - @Override - public void onStreamUnpublished(String url) { - if(url != null && !unpublishing && retried < MAX_RETRY_TIMES){ - engine.addPublishStreamUrl(et_url.getText().toString(), transCodeSwitch.isChecked()); - retried++; - } - if(unpublishing){ - unpublishing = false; - } - } - - /** - * Reports the result of calling the addPublishStreamUrl method. - * This callback indicates whether you have successfully added an RTMP or RTMPS stream to the CDN. - * @param url The CDN streaming URL. - * @param error The detailed error information: - */ - @Override - public void onStreamPublished(String url, int error) { - if(error == ERR_OK){ - retried = 0; - retryTask.cancel(true); - } - else{ - switch (error){ - case ERR_FAILED: - case ERR_TIMEDOUT: - case ERR_PUBLISH_STREAM_INTERNAL_SERVER_ERROR: - engine.removePublishStreamUrl(url); - break; - case ERR_PUBLISH_STREAM_NOT_FOUND: - if(retried < MAX_RETRY_TIMES){ - engine.addPublishStreamUrl(et_url.getText().toString(), transCodeSwitch.isChecked()); - retried++; - } - break; - } - } - } - /**Occurs when a remote user (Communication)/host (Live Broadcast) joins the channel. * @param uid ID of the user whose audio state changes. * @param elapsed Time delay (ms) from the local user calling joinChannel/setClientRole @@ -655,9 +594,9 @@ public void onUserJoined(int uid, int elapsed) { transcodingUser.width = transcoding.width; transcodingUser.height = transcoding.height / MAXUserCount; transcodingUser.uid = uid; - int ret = transcoding.addUser(transcodingUser); + transcoding.addUser(transcodingUser); /**refresh transCoding configuration*/ - engine.setLiveTranscoding(transcoding); + int ret = engine.updateRtmpTranscoding(transcoding); } } @@ -698,7 +637,7 @@ public void run() { int code = transcoding.removeUser(uid); if (code == ERR_OK) { /**refresh transCoding configuration*/ - engine.setLiveTranscoding(transcoding); + engine.updateRtmpTranscoding(transcoding); } } } 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 a10ecb1a4..f32292705 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 @@ -93,7 +93,7 @@ android:layout_weight="1" android:hint="@string/url" android:singleLine="true" - android:text="" /> + android:text="rtmp://webdemo-push.agora.io/lbhd/xxx" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Android/APIExample/app/src/main/res/navigation/nav_graph.xml b/Android/APIExample/app/src/main/res/navigation/nav_graph.xml index 05bab2085..2085c0933 100755 --- a/Android/APIExample/app/src/main/res/navigation/nav_graph.xml +++ b/Android/APIExample/app/src/main/res/navigation/nav_graph.xml @@ -20,9 +20,6 @@ - @@ -56,9 +53,6 @@ - @@ -107,6 +101,9 @@ + - - + 此示例演示了在音视频通话过程中如何伴随视频帧发送数据流信息的方法。 此示例演示了在音频通话过程中如何通过回调获取裸数据的功能。 音频耳返 + 此示例演示了音频通话过程中SDK内置的各类视频增强功能。 混音控制 开始 恢复播放 @@ -163,4 +164,18 @@ 录制倒计时 播放倒计时 开始麦克风录制 + 美颜 + 虚拟节拍器 + Beats per Measure + Beats per Minute + 美颜 + 美白 + 红润 + 锐利 + 平滑 + 暗光增强 + 色彩增强 + 视频降噪 + 强度 + 肤色保护 \ No newline at end of file diff --git a/Android/APIExample/app/src/main/res/values/strings.xml b/Android/APIExample/app/src/main/res/values/strings.xml index 3f82e0f55..c7813b111 100644 --- a/Android/APIExample/app/src/main/res/values/strings.xml +++ b/Android/APIExample/app/src/main/res/values/strings.xml @@ -136,6 +136,7 @@ This example shows how to use sendDataStream API to send your custom data along with Video Frame in Channel. This example shows how to register Audio Observer to engine for extract raw audio data during RTC communication Audio Loopback + This example shows the features for video enhancement for RTC communication. Audio Mixing Control Start Resume @@ -167,4 +168,18 @@ Recording Countdown Playing Countdown Recording on Microphone + Face Beautify + Rhythm Player + Beats per Measure + Beats per Minute + Face Beautify + Lightening + Redness + Sharpness + Lightening Enhance + Colorful Enhance + Smoothness + Video Denoise + Strength + Skin Protect From 5cc36a15f4fd874f2bc1fe7717d10472a907e4b2 Mon Sep 17 00:00:00 2001 From: xianing Date: Thu, 2 Dec 2021 14:02:42 +0800 Subject: [PATCH 02/13] update iOS: rtmp streaming, video processor --- .../examples/advanced/RTMPStreaming.java | 37 +-- .../res/layout/fragment_rtmp_streaming.xml | 2 +- iOS/APIExample.xcodeproj/project.pbxproj | 185 +++++++++++-- .../JoinMultiChannel/JoinMultiChannel.swift | 8 +- .../RTMPStreaming/RTMPStreaming.swift | 117 ++++---- .../Base.lproj/VideoProcess.storyboard | 220 +++++++++++++++ .../Advanced/VideoProcess/VideoProcess.swift | 252 ++++++++++++++++++ .../zh-Hans.lproj/VideoProcess.strings | 51 ++++ iOS/APIExample/ViewController.swift | 1 + .../zh-Hans.lproj/Localizable.strings | 3 + 10 files changed, 771 insertions(+), 105 deletions(-) create mode 100644 iOS/APIExample/Examples/Advanced/VideoProcess/Base.lproj/VideoProcess.storyboard create mode 100644 iOS/APIExample/Examples/Advanced/VideoProcess/VideoProcess.swift create mode 100644 iOS/APIExample/Examples/Advanced/VideoProcess/zh-Hans.lproj/VideoProcess.strings 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 78b4e1093..3a9fcfba4 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 @@ -282,7 +282,7 @@ protected Object doInBackground(Object[] objects) { Log.e(TAG, e.getMessage()); break; } - result = engine.addPublishStreamUrl(et_url.getText().toString(), transCodeSwitch.isChecked()); + result = startRtmpStreaming(); } return result; } @@ -528,32 +528,33 @@ public void onRtmpStreamingStateChanged(String url, int state, int errorType) { || errorType == RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR)) { /**if failed, make changes to the UI.*/ - publishing = true; retryTask.cancel(true); + unpublishing = true; + } + } else if (state == Constants.RTMP_STREAM_PUBLISH_STATE_IDLE) { + if(unpublishing){ + unpublishing = false; + /**Push stream not started or ended, make changes to the UI.*/ handler.post(() -> { publish.setEnabled(true); publish.setText(getString(R.string.publish)); transCodeSwitch.setEnabled(true); - publishing = false; }); } - else if(url != null && !unpublishing && retried < MAX_RETRY_TIMES - ){ - startRtmpStreaming(); - retried++; + else if( retried >= MAX_RETRY_TIMES){ + retryTask.cancel(true); + retried = 0; + /**Push stream not started or ended, make changes to the UI.*/ + handler.post(() -> { + publish.setEnabled(true); + publish.setText(getString(R.string.publish)); + transCodeSwitch.setEnabled(true); + }); } - } else if (state == Constants.RTMP_STREAM_PUBLISH_STATE_IDLE) { - if(unpublishing){ - unpublishing = false; + else{ + retried++; + startRtmpStreaming(); } - /**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; - }); } } 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 f32292705..a10ecb1a4 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 @@ -93,7 +93,7 @@ android:layout_weight="1" android:hint="@string/url" android:singleLine="true" - android:text="rtmp://webdemo-push.agora.io/lbhd/xxx" /> + android:text="" /> = MAX_RETRY_TIMES { - return - } - guard let rtmpURL = rtmpTextField.text else { - return - } - let transcodingEnabled = transcodingSwitch.isOn - agoraKit.addPublishStreamUrl(rtmpURL, transcodingEnabled: transcodingEnabled) + if state == .running { + if errorCode == .streamingErrorCodeOK { + self.showAlert(title: "Notice", message: "RTMP Publish Success") + isPublished = true + stopRetryTimer() + retried = 0 + } + } else if state == .failure { + agoraKit.stopRtmpStream(rtmpURL) + if errorCode == .streamingErrorCodeInternalServerError || errorCode == .streamingErrorCodeConnectionTimeout { + self.showAlert(title: "Error", message: "RTMP Publish Failed: \(errorCode.rawValue)") + stopRetryTimer() + unpublishing = true + } + } else if state == .idle { + if unpublishing { + unpublishing = false + self.showAlert(title: "Notice", message: "RTMP Publish Stopped") + isPublished = false + } + else if retried >= MAX_RETRY_TIMES{ + stopRetryTimer() + retried = 0 + self.showAlert(title: "Notice", message: "RTMP Publish Stopped") + isPublished = false + } + else { retried += 1 - default: - print("unhandled rtmp streaming error: \(errorCode.rawValue)") + startRtmpStreaming(isTranscoding: transcodingSwitch.isOn, rtmpURL: rtmpURL) } } } - func rtcEngine(_ engine: AgoraRtcEngineKit, streamUnpublishedWithUrl url: String) { - if unpublishing || retried >= MAX_RETRY_TIMES { - return - } - guard let rtmpURL = rtmpTextField.text else { - return - } - let transcodingEnabled = transcodingSwitch.isOn - agoraKit.addPublishStreamUrl(rtmpURL, transcodingEnabled: transcodingEnabled) - retried += 1 - if(unpublishing){ - unpublishing = false; + func rtcEngine(_ engine: AgoraRtcEngineKit, rtmpStreamingEventWithUrl url: String, eventCode: AgoraRtmpStreamingEvent) { + if(eventCode == .urlAlreadyInUse) { + self.showAlert(title: "Error", message: "The URL is already in Use.") } } diff --git a/iOS/APIExample/Examples/Advanced/VideoProcess/Base.lproj/VideoProcess.storyboard b/iOS/APIExample/Examples/Advanced/VideoProcess/Base.lproj/VideoProcess.storyboard new file mode 100644 index 000000000..7575139b5 --- /dev/null +++ b/iOS/APIExample/Examples/Advanced/VideoProcess/Base.lproj/VideoProcess.storyboard @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/APIExample/Examples/Advanced/VideoProcess/VideoProcess.swift b/iOS/APIExample/Examples/Advanced/VideoProcess/VideoProcess.swift new file mode 100644 index 000000000..6ceea24c7 --- /dev/null +++ b/iOS/APIExample/Examples/Advanced/VideoProcess/VideoProcess.swift @@ -0,0 +1,252 @@ +// +// VideoProcess.swift +// APIExample +// +// Created by xianing on 2021/11/12. +// Copyright © 2021 Agora Corp. All rights reserved. +// + +import UIKit +import AgoraRtcKit +import AGEVideoLayout + +class VideoProcessEntry : UIViewController +{ + @IBOutlet weak var joinButton: AGButton! + @IBOutlet weak var channelTextField: AGTextField! + let identifier = "VideoProcess" + + override func viewDidLoad() { + super.viewDidLoad() + } + + @IBAction func doJoinPressed(sender: AGButton) { + guard let channelName = channelTextField.text else {return} + //resign channel text field + channelTextField.resignFirstResponder() + + let storyBoard: UIStoryboard = UIStoryboard(name: identifier, bundle: nil) + // create new view controller every time to ensure we get a clean vc + guard let newViewController = storyBoard.instantiateViewController(withIdentifier: identifier) as? BaseViewController else {return} + newViewController.title = channelName + newViewController.configs = ["channelName":channelName] + self.navigationController?.pushViewController(newViewController, animated: true) + } +} + +class VideoProcessMain : BaseViewController +{ + var localVideo = Bundle.loadVideoView(type: .local, audioOnly: false) + var remoteVideo = Bundle.loadVideoView(type: .remote, audioOnly: false) + + @IBOutlet weak var container: AGEVideoContainer! + var agoraKit: AgoraRtcEngineKit! + + @IBOutlet weak var beauty: UISwitch! + @IBOutlet weak var lightness: UISwitch! + @IBOutlet weak var colorful: UISwitch! + @IBOutlet weak var denoiser: UISwitch! + + @IBOutlet weak var lightenSlider: UISlider! + @IBOutlet weak var rednessSlider: UISlider! + @IBOutlet weak var sharpnessSlider: UISlider! + @IBOutlet weak var smoothSlider: UISlider! + + // indicate if current instance has joined channel + var isJoined: Bool = false + var beautifyOption = AgoraBeautyOptions() + var skinProtect = 1.0 + var strength = 0.5 + + override func viewDidLoad(){ + super.viewDidLoad() + // layout render view + localVideo.setPlaceholder(text: "Local Host".localized) + remoteVideo.setPlaceholder(text: "Remote Host".localized) + container.layoutStream(views: [localVideo, remoteVideo]) + + // set up agora instance when view loaded + let config = AgoraRtcEngineConfig() + config.appId = KeyCenter.AppId + config.areaCode = GlobalSettings.shared.area.rawValue + + // setup log file path + let logConfig = AgoraLogConfig() + logConfig.level = .info + config.logConfig = logConfig + + agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self) + + // get channel name from configs + guard let channelName = configs["channelName"] as? String, + let resolution = GlobalSettings.shared.getSetting(key: "resolution")?.selectedOption().value as? CGSize, + let fps = GlobalSettings.shared.getSetting(key: "fps")?.selectedOption().value as? AgoraVideoFrameRate, + let orientation = GlobalSettings.shared.getSetting(key: "orientation")?.selectedOption().value as? AgoraVideoOutputOrientationMode else {return} + + // make myself a broadcaster + agoraKit.setChannelProfile(.liveBroadcasting) + agoraKit.setClientRole(.broadcaster) + + // enable video module and set up video encoding configs + agoraKit.enableVideo() + agoraKit.setVideoEncoderConfiguration(AgoraVideoEncoderConfiguration(size: resolution, + frameRate: fps, + bitrate: AgoraVideoBitrateStandard, + orientationMode: orientation)) + + // set up local video to render your local camera preview + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = 0 + // the view to be binded + videoCanvas.view = localVideo.videoView + videoCanvas.renderMode = .hidden + agoraKit.setupLocalVideo(videoCanvas) + + // Set audio route to speaker + agoraKit.setDefaultAudioRouteToSpeakerphone(true) + + // start joining channel + // 1. Users can only see each other after they join the + // same channel successfully using the same app id. + // 2. If app certificate is turned on at dashboard, token is needed + // when joining channel. The channel name and uid used to calculate + // the token has to match the ones used for channel join + let option = AgoraRtcChannelMediaOptions() + let result = agoraKit.joinChannel(byToken: KeyCenter.Token, channelId: channelName, info: nil, uid: 0, options: option) + if result != 0 { + // Usually happens with invalid parameters + // Error code description can be found at: + // en: https://docs.agora.io/en/Voice/API%20Reference/oc/Constants/AgoraErrorCode.html + // cn: https://docs.agora.io/cn/Voice/API%20Reference/oc/Constants/AgoraErrorCode.html + self.showAlert(title: "Error", message: "joinChannel call failed: \(result), please check your params") + } + } + + override func willMove(toParent parent: UIViewController?) { + if parent == nil { + // leave channel when exiting the view + if isJoined { + agoraKit.leaveChannel { (stats) -> Void in + LogUtils.log(message: "left channel, duration: \(stats.duration)", level: .info) + } + } + } + } + + @IBAction func onLightenSlider(_ sender:UISlider){ + beautifyOption.lighteningLevel = sender.value + agoraKit.setBeautyEffectOptions(beauty.isOn, options: beautifyOption) + } + @IBAction func onRednessSlider(_ sender:UISlider){ + beautifyOption.rednessLevel = sender.value + agoraKit.setBeautyEffectOptions(beauty.isOn, options: beautifyOption) + } + @IBAction func onSharpnessSlider(_ sender:UISlider){ + beautifyOption.sharpnessLevel = sender.value + agoraKit.setBeautyEffectOptions(beauty.isOn, options: beautifyOption) + } + @IBAction func onSmoothSlider(_ sender:UISlider){ + beautifyOption.smoothnessLevel = sender.value + agoraKit.setBeautyEffectOptions(beauty.isOn, options: beautifyOption) + } + @IBAction func onChangeBeauty(_ sender:UISwitch){ + agoraKit.setBeautyEffectOptions(sender.isOn, options: beautifyOption) + } +} + +extension VideoProcessMain: AgoraRtcEngineDelegate { + /// callback when warning occured for agora sdk, warning can usually be ignored, still it's nice to check out + /// what is happening + /// Warning code description can be found at: + /// en: https://docs.agora.io/en/Voice/API%20Reference/oc/Constants/AgoraWarningCode.html + /// cn: https://docs.agora.io/cn/Voice/API%20Reference/oc/Constants/AgoraWarningCode.html + /// @param warningCode warning code of the problem + func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurWarning warningCode: AgoraWarningCode) { + LogUtils.log(message: "warning: \(warningCode.description)", level: .warning) + } + + /// callback when error occured for agora sdk, you are recommended to display the error descriptions on demand + /// to let user know something wrong is happening + /// Error code description can be found at: + /// en: https://docs.agora.io/en/Voice/API%20Reference/oc/Constants/AgoraErrorCode.html + /// cn: https://docs.agora.io/cn/Voice/API%20Reference/oc/Constants/AgoraErrorCode.html + /// @param errorCode error code of the problem + func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurError errorCode: AgoraErrorCode) { + LogUtils.log(message: "error: \(errorCode)", level: .error) + self.showAlert(title: "Error", message: "Error \(errorCode.description) occur") + } + + /// callback when the local user joins a specified channel. + /// @param channel + /// @param uid uid of local user + /// @param elapsed time elapse since current sdk instance join the channel in ms + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { + self.isJoined = true + LogUtils.log(message: "Join \(channel) with uid \(uid) elapsed \(elapsed)ms", level: .info) + } + + /// callback when a remote user is joinning the channel, note audience in live broadcast mode will NOT trigger this event + /// @param uid uid of remote joined user + /// @param elapsed time elapse since current sdk instance join the channel in ms + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { + LogUtils.log(message: "remote user join: \(uid) \(elapsed)ms", level: .info) + + // Only one remote video view is available for this + // tutorial. Here we check if there exists a surface + // view tagged as this uid. + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + // the view to be binded + videoCanvas.view = remoteVideo.videoView + videoCanvas.renderMode = .hidden + agoraKit.setupRemoteVideo(videoCanvas) + } + + /// callback when a remote user is leaving the channel, note audience in live broadcast mode will NOT trigger this event + /// @param uid uid of remote joined user + /// @param reason reason why this user left, note this event may be triggered when the remote user + /// become an audience in live broadcasting profile + func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { + LogUtils.log(message: "remote user left: \(uid) reason \(reason)", level: .info) + + // to unlink your view from sdk, so that your view reference will be released + // note the video will stay at its last frame, to completely remove it + // you will need to remove the EAGL sublayer from your binded view + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + // the view to be binded + videoCanvas.view = nil + videoCanvas.renderMode = .hidden + agoraKit.setupRemoteVideo(videoCanvas) + } + + /// Reports the statistics of the current call. The SDK triggers this callback once every two seconds after the user joins the channel. + /// @param stats stats struct + func rtcEngine(_ engine: AgoraRtcEngineKit, reportRtcStats stats: AgoraChannelStats) { + localVideo.statsInfo?.updateChannelStats(stats) + } + + /// Reports the statistics of the uploading local video streams once every two seconds. + /// @param stats stats struct + func rtcEngine(_ engine: AgoraRtcEngineKit, localVideoStats stats: AgoraRtcLocalVideoStats) { + localVideo.statsInfo?.updateLocalVideoStats(stats) + } + + /// Reports the statistics of the uploading local audio streams once every two seconds. + /// @param stats stats struct + func rtcEngine(_ engine: AgoraRtcEngineKit, localAudioStats stats: AgoraRtcLocalAudioStats) { + localVideo.statsInfo?.updateLocalAudioStats(stats) + } + + /// Reports the statistics of the video stream from each remote user/host. + /// @param stats stats struct + func rtcEngine(_ engine: AgoraRtcEngineKit, remoteVideoStats stats: AgoraRtcRemoteVideoStats) { + remoteVideo.statsInfo?.updateVideoStats(stats) + } + + /// Reports the statistics of the audio stream from each remote user/host. + /// @param stats stats struct for current call statistics + func rtcEngine(_ engine: AgoraRtcEngineKit, remoteAudioStats stats: AgoraRtcRemoteAudioStats) { + remoteVideo.statsInfo?.updateAudioStats(stats) + } +} diff --git a/iOS/APIExample/Examples/Advanced/VideoProcess/zh-Hans.lproj/VideoProcess.strings b/iOS/APIExample/Examples/Advanced/VideoProcess/zh-Hans.lproj/VideoProcess.strings new file mode 100644 index 000000000..fc209274c --- /dev/null +++ b/iOS/APIExample/Examples/Advanced/VideoProcess/zh-Hans.lproj/VideoProcess.strings @@ -0,0 +1,51 @@ + +/* Class = "UISwitch"; title = "Face Beautify"; ObjectID = "0lt-yn-0yl"; */ +"0lt-yn-0yl.title" = "美颜"; + +/* Class = "UIButton"; normalTitle = "Join"; ObjectID = "1Vr-cE-fQI"; */ +"1Vr-cE-fQI.normalTitle" = "加入"; + +/* Class = "UILabel"; text = "Lightening Enhance"; ObjectID = "2y0-8E-3Er"; */ +"2y0-8E-3Er.text" = "暗光增强"; + +/* Class = "UILabel"; text = "Smoothness"; ObjectID = "3Cr-C9-PWm"; */ +"3Cr-C9-PWm.text" = "平滑"; + +/* Class = "UISwitch"; title = "Face Beautify"; ObjectID = "3jT-PF-fry"; */ +"3jT-PF-fry.title" = "美颜"; + +/* Class = "UILabel"; text = "Lightening"; ObjectID = "6Yy-cm-VP3"; */ +"6Yy-cm-VP3.text" = "美白"; + +/* Class = "UIViewController"; title = "Simple Filter"; ObjectID = "8Zn-pj-gkm"; */ +"8Zn-pj-gkm.title" = "视频增强"; + +/* Class = "UISwitch"; title = "Face Beautify"; ObjectID = "HJK-u9-Pbi"; */ +"HJK-u9-Pbi.title" = "美颜"; + +/* Class = "UILabel"; text = "Video Denoiser"; ObjectID = "IK4-hW-gbx"; */ +"IK4-hW-gbx.text" = "视频降噪"; + +/* Class = "UILabel"; text = "Colorful Enhance"; ObjectID = "Ijy-ys-cZf"; */ +"Ijy-ys-cZf.text" = "色彩增强"; + +/* Class = "UILabel"; text = "Face Beautify"; ObjectID = "Ty6-YP-tus"; */ +"Ty6-YP-tus.text" = "美颜"; + +/* Class = "UISwitch"; title = "Face Beautify"; ObjectID = "YBf-iq-ZSD"; */ +"YBf-iq-ZSD.title" = "美颜"; + +/* Class = "UILabel"; text = "Redness"; ObjectID = "c7I-oU-1Ty"; */ +"c7I-oU-1Ty.text" = "红润"; + +/* Class = "UITextField"; placeholder = "Enter channel name"; ObjectID = "moa-hL-hhA"; */ +"moa-hL-hhA.placeholder" = "请输入频道名"; + +/* Class = "UILabel"; text = "Sharpness"; ObjectID = "nxu-z3-DfB"; */ +"nxu-z3-DfB.text" = "锐利"; + +/* Class = "UILabel"; text = "Strength"; ObjectID = "OIO-FL-y7u"; */ +"OIO-FL-y7u.text" = "强度"; + +/* Class = "UILabel"; text = "Skin Protect"; ObjectID = "C1K-xQ-TKU"; */ +"C1K-xQ-TKU.text" = "肤色保护"; diff --git a/iOS/APIExample/ViewController.swift b/iOS/APIExample/ViewController.swift index a578aa2e0..6c8e7d55e 100644 --- a/iOS/APIExample/ViewController.swift +++ b/iOS/APIExample/ViewController.swift @@ -47,6 +47,7 @@ class ViewController: AGViewController { MenuItem(name: "Audio Mixing".localized, storyboard: "AudioMixing", controller: ""), MenuItem(name: "Precall Test".localized, storyboard: "PrecallTest", controller: ""), MenuItem(name: "Screen Share".localized, storyboard: "ScreenShare", controller: ""), + MenuItem(name: "Video Process".localized, storyboard: "VideoProcess", controller: "VideoProcess"), MenuItem(name: "Super Resolution".localized, storyboard: "SuperResolution", controller: ""), MenuItem(name: "Media Channel Relay".localized, storyboard: "MediaChannelRelay", controller: ""), MenuItem(name: "Media Player".localized, storyboard: "MediaPlayer", controller: "MediaPlayer"), diff --git a/iOS/APIExample/zh-Hans.lproj/Localizable.strings b/iOS/APIExample/zh-Hans.lproj/Localizable.strings index 53e35c092..d94826531 100644 --- a/iOS/APIExample/zh-Hans.lproj/Localizable.strings +++ b/iOS/APIExample/zh-Hans.lproj/Localizable.strings @@ -117,7 +117,10 @@ "Sweet" = "甜美"; "Solid" = "稳重"; "Bass" = "重低音"; +"Video Process" = "美颜"; "Start Audio Test" = "开始音频测试"; "Stop Audio Test" = "停止音频测试"; "Start Video/Audio Test" = "开始音视频测试"; "Stop Video/Audio Test" = "停止音视频测试"; +"push" = "推流"; +"stop" = "停止"; From 66f380451c5b815d942be491ccac000fe844bb5f Mon Sep 17 00:00:00 2001 From: xianing Date: Fri, 3 Dec 2021 00:30:03 +0800 Subject: [PATCH 03/13] adapt 3.6.0 for macos --- .../examples/advanced/RTMPStreaming.java | 6 +- .../CustomPcmAudioSource.swift | 1 - .../RTMPStreaming/RTMPStreaming.swift | 5 +- .../JoinMultiChannel/JoinMultiChannel.swift | 18 +++--- .../RTMPStreaming/RTMPStreaming.swift | 61 ++++++++++--------- .../Advanced/ScreenShare/ScreenShare.swift | 11 ++-- 6 files changed, 57 insertions(+), 45 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 3a9fcfba4..db2d94a22 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 @@ -42,7 +42,9 @@ import static io.agora.rtc.Constants.ERR_TIMEDOUT; import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_CONNECTION_TIMEOUT; import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR; +import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_NET_DOWN; import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_OK; +import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_STREAM_NOT_FOUND; import static io.agora.rtc.video.VideoCanvas.RENDER_MODE_HIDDEN; import static io.agora.rtc.video.VideoEncoderConfiguration.STANDARD_BITRATE; import static io.agora.rtc.video.VideoEncoderConfiguration.VD_640x360; @@ -525,7 +527,9 @@ public void onRtmpStreamingStateChanged(String url, int state, int errorType) { } else if (state == Constants.RTMP_STREAM_PUBLISH_STATE_FAILURE) { engine.stopRtmpStream(et_url.getText().toString()); if((errorType == RTMP_STREAM_PUBLISH_ERROR_CONNECTION_TIMEOUT - || errorType == RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR)) + || errorType == RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR + || errorType == RTMP_STREAM_PUBLISH_ERROR_STREAM_NOT_FOUND + || errorType == RTMP_STREAM_PUBLISH_ERROR_NET_DOWN)) { /**if failed, make changes to the UI.*/ retryTask.cancel(true); diff --git a/iOS/APIExample/Examples/Advanced/CustomPcmAudioSource/CustomPcmAudioSource.swift b/iOS/APIExample/Examples/Advanced/CustomPcmAudioSource/CustomPcmAudioSource.swift index dcda2f7c1..1f275c922 100644 --- a/iOS/APIExample/Examples/Advanced/CustomPcmAudioSource/CustomPcmAudioSource.swift +++ b/iOS/APIExample/Examples/Advanced/CustomPcmAudioSource/CustomPcmAudioSource.swift @@ -156,7 +156,6 @@ extension CustomPcmAudioSourceMain: AgoraPcmSourcePushDelegate { frame.bytesPerSample = 32 * 8 frame.samplesPerChannel = self.samples / 2 let ret = agoraKit.pushExternalAudioFrameRawData(pushPos, frame: frame) - agoraKit.pushExternalAudioFrameRawData(data, samples: samples, timestamp: 0) print("push result: \(ret)") } } diff --git a/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift b/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift index 42f36b903..558fdd3e5 100644 --- a/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift +++ b/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift @@ -331,7 +331,10 @@ extension RTMPStreamingMain: AgoraRtcEngineDelegate { } } else if state == .failure { agoraKit.stopRtmpStream(rtmpURL) - if errorCode == .streamingErrorCodeInternalServerError || errorCode == .streamingErrorCodeConnectionTimeout { + if errorCode == .streamingErrorCodeInternalServerError + || errorCode == .streamingErrorCodeStreamNotFound + || errorCode == .streamPublishErrorNetDown + || errorCode == .streamingErrorCodeConnectionTimeout { self.showAlert(title: "Error", message: "RTMP Publish Failed: \(errorCode.rawValue)") stopRetryTimer() unpublishing = true diff --git a/macOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift b/macOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift index fc966250b..0a675a3f8 100644 --- a/macOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift +++ b/macOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift @@ -75,7 +75,7 @@ class JoinMultipleChannel: BaseViewController { } } else { channel1?.leave() - if let channelName = channel1?.getId() { + if let channelName = channel1?.getChannelId() { if isPublished && channelName == selectedChannel { if let channel = getChannelByName(selectedChannel) { channel.setClientRole(.audience) @@ -147,7 +147,7 @@ class JoinMultipleChannel: BaseViewController { } } else { channel2?.leave() - if let channelName = channel2?.getId() { + if let channelName = channel2?.getChannelId() { if isPublished && channelName == selectedChannel { if let channel = getChannelByName(selectedChannel) { channel.setClientRole(.audience) @@ -258,9 +258,9 @@ class JoinMultipleChannel: BaseViewController { } func getChannelByName(_ channelName: String?) -> AgoraRtcChannel? { - if channel1?.getId() == channelName { + if channel1?.getChannelId() == channelName { return channel1 - } else if channel2?.getId() == channelName { + } else if channel2?.getChannelId() == channelName { return channel2 } return nil @@ -305,8 +305,8 @@ extension JoinMultipleChannel: AgoraRtcEngineDelegate { extension JoinMultipleChannel: AgoraRtcChannelDelegate { func rtcChannelDidJoin(_ rtcChannel: AgoraRtcChannel, withUid uid: UInt, elapsed: Int) { - LogUtils.log(message: "Join \(rtcChannel.getId() ?? "") with uid \(uid) elapsed \(elapsed)ms", level: .info) - selectChannelsPicker.picker.addItem(withTitle: rtcChannel.getId()!) + LogUtils.log(message: "Join \(rtcChannel.getChannelId() ?? "") with uid \(uid) elapsed \(elapsed)ms", level: .info) + selectChannelsPicker.picker.addItem(withTitle: rtcChannel.getChannelId()!) if (channel1 == rtcChannel) { isJoined = true } else { @@ -320,7 +320,7 @@ extension JoinMultipleChannel: AgoraRtcChannelDelegate { /// cn: https://docs.agora.io/cn/Voice/API%20Reference/oc/Constants/AgoraWarningCode.html /// @param warningCode warning code of the problem func rtcChannel(_ rtcChannel: AgoraRtcChannel, didOccurWarning warningCode: AgoraWarningCode) { - LogUtils.log(message: "channel: \(rtcChannel.getId() ?? ""), warning: \(warningCode.rawValue)", level: .warning) + LogUtils.log(message: "channel: \(rtcChannel.getChannelId() ?? ""), warning: \(warningCode.rawValue)", level: .warning) } /// callback when error occured for a channel, you are recommended to display the error descriptions on demand @@ -349,7 +349,7 @@ extension JoinMultipleChannel: AgoraRtcChannelDelegate { videoCanvas.view = channel1 == rtcChannel ? videos2[0].videocanvas : videos2[1].videocanvas videoCanvas.renderMode = .hidden // set channelId so that it knows which channel the video belongs to - videoCanvas.channelId = rtcChannel.getId() + videoCanvas.channelId = rtcChannel.getChannelId() agoraKit.setupRemoteVideo(videoCanvas) } @@ -369,7 +369,7 @@ extension JoinMultipleChannel: AgoraRtcChannelDelegate { videoCanvas.view = nil videoCanvas.renderMode = .hidden // set channelId so that it knows which channel the video belongs to - videoCanvas.channelId = rtcChannel.getId() + videoCanvas.channelId = rtcChannel.getChannelId() agoraKit.setupRemoteVideo(videoCanvas) } } diff --git a/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift b/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift index a814b1383..ef81f9e17 100644 --- a/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift +++ b/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift @@ -20,7 +20,7 @@ class RTMPStreaming: BaseViewController { var agoraKit: AgoraRtcEngineKit! var transcoding = AgoraLiveTranscoding.default() - + /** --- rtmpUrls Picker --- */ @@ -47,7 +47,7 @@ class RTMPStreaming: BaseViewController { rtmpURLs.remove(at: selectRtmpUrlsPicker.indexOfSelectedItem) selectRtmpUrlsPicker.picker.removeItem(at: selectRtmpUrlsPicker.indexOfSelectedItem) } - + /// callback when remove all streaming url button hit @IBAction func onRemoveAllStreamingURL(_ sender: Any) { for url in rtmpURLs { @@ -56,7 +56,7 @@ class RTMPStreaming: BaseViewController { rtmpURLs = [] selectRtmpUrlsPicker.picker.removeAllItems() } - + /** --- Channel TextField --- */ @@ -65,7 +65,7 @@ class RTMPStreaming: BaseViewController { channelField.label.stringValue = "Channel".localized channelField.field.placeholderString = "Channel Name".localized } - + /** --- rtmp TextField --- */ @@ -89,21 +89,26 @@ class RTMPStreaming: BaseViewController { showAlert(title: "Add Streaming URL Failed", message: "RTMP URL cannot be empty or not start with 'rtmp://'") return } - + if transcodingEnabled { // we will use transcoding to composite multiple hosts' video // therefore we have to create a livetranscoding object and call before addPublishStreamUrl transcoding.size = CGSize(width: CANVAS_WIDTH, height: CANVAS_HEIGHT) - agoraKit.setLiveTranscoding(transcoding) + agoraKit.updateRtmpTranscoding(transcoding) } - + // start publishing to this URL - agoraKit.addPublishStreamUrl(rtmpURL, transcodingEnabled: transcodingEnabled) + if transcodingEnabled { + agoraKit.startRtmpStreamWithTranscoding(rtmpURL, transcoding: transcoding) + } + else { + agoraKit.startRtmpStreamWithoutTranscoding(rtmpURL) + } // update properties and UI rtmpURLs.append(rtmpURL) selectRtmpUrlsPicker.picker.addItem(withTitle: rtmpURL) } - + /** --- Button --- */ @@ -111,7 +116,7 @@ class RTMPStreaming: BaseViewController { func initJoinChannelButton() { joinChannelButton.title = isJoined ? "Leave Channel".localized : "Join Channel".localized } - + // indicate if current instance has joined channel var isJoined: Bool = false { didSet { @@ -119,14 +124,14 @@ class RTMPStreaming: BaseViewController { initJoinChannelButton() } } - + // indicate for doing something var isProcessing: Bool = false { didSet { joinChannelButton.isEnabled = !isProcessing } } - + override func viewDidLoad() { super.viewDidLoad() layoutVideos(2) @@ -136,13 +141,13 @@ class RTMPStreaming: BaseViewController { config.areaCode = GlobalSettings.shared.area.rawValue agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self) agoraKit.enableVideo() - + initSelectRtmpUrlsPicker() initRtmpURLField() initChannelField() initJoinChannelButton() } - + override func viewWillBeRemovedFromSplitView() { if isJoined { agoraKit.leaveChannel { (stats:AgoraChannelStats) in @@ -151,7 +156,7 @@ class RTMPStreaming: BaseViewController { } AgoraRtcEngineKit.destroy() } - + @IBAction func onJoinPressed(_ sender:Any) { if !isJoined { // check configuration @@ -180,7 +185,7 @@ class RTMPStreaming: BaseViewController { videoCanvas.view = localVideo.videocanvas videoCanvas.renderMode = .hidden agoraKit.setupLocalVideo(videoCanvas) - + // start joining channel // 1. Users can only see each other after they join the // same channel successfully using the same app id. @@ -240,7 +245,7 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurWarning warningCode: AgoraWarningCode) { LogUtils.log(message: "warning: \(warningCode.rawValue)", level: .warning) } - + /// callback when error occured for agora sdk, you are recommended to display the error descriptions on demand /// to let user know something wrong is happening /// Error code description can be found at: @@ -254,7 +259,7 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { } self.showAlert(title: "Error", message: "Error \(errorCode.rawValue) occur") } - + /// callback when the local user joins a specified channel. /// @param channel /// @param uid uid of local user @@ -265,7 +270,7 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { let localVideo = videos[0] localVideo.uid = uid LogUtils.log(message: "Join \(channel) with uid \(uid) elapsed \(elapsed)ms", level: .info) - + // add transcoding user so the video stream will be involved // in future RTMP Stream let user = AgoraLiveTranscodingUser() @@ -273,13 +278,13 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { user.uid = uid transcoding.add(user) } - + /// callback when a remote user is joinning the channel, note audience in live broadcast mode will NOT trigger this event /// @param uid uid of remote joined user /// @param elapsed time elapse since current sdk instance join the channel in ms func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { LogUtils.log(message: "remote user join: \(uid) \(elapsed)ms", level: .info) - + // find a VideoView w/o uid assigned if let remoteVideo = videos.first(where: { $0.uid == nil }) { let videoCanvas = AgoraRtcVideoCanvas() @@ -292,7 +297,7 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { } else { LogUtils.log(message: "no video canvas available for \(uid), cancel bind", level: .warning) } - + // update live transcoding // add new user onto the canvas let user = AgoraLiveTranscodingUser() @@ -300,16 +305,16 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { user.uid = uid self.transcoding.add(user) // remember you need to call setLiveTranscoding again if you changed the layout - agoraKit.setLiveTranscoding(transcoding) + agoraKit.updateRtmpTranscoding(transcoding) } - + /// callback when a remote user is leaving the channel, note audience in live broadcast mode will NOT trigger this event /// @param uid uid of remote joined user /// @param reason reason why this user left, note this event may be triggered when the remote user /// become an audience in live broadcasting profile func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { LogUtils.log(message: "remote user left: \(uid) reason \(reason)", level: .info) - + // to unlink your view from sdk, so that your view reference will be released // note the video will stay at its last frame, to completely remove it // you will need to remove the EAGL sublayer from your binded view @@ -324,13 +329,13 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { } else { LogUtils.log(message: "no matching video canvas for \(uid), cancel unbind", level: .warning) } - + // remove user from canvas if current cohost left channel transcoding.removeUser(uid) // remember you need to call setLiveTranscoding again if you changed the layout - agoraKit.setLiveTranscoding(transcoding) + agoraKit.updateRtmpTranscoding(transcoding) } - + /// callback for state of rtmp streaming, for both good and bad state /// @param url rtmp streaming url /// @param state state of rtmp streaming diff --git a/macOS/APIExample/Examples/Advanced/ScreenShare/ScreenShare.swift b/macOS/APIExample/Examples/Advanced/ScreenShare/ScreenShare.swift index 644a30842..a94a8935e 100644 --- a/macOS/APIExample/Examples/Advanced/ScreenShare/ScreenShare.swift +++ b/macOS/APIExample/Examples/Advanced/ScreenShare/ScreenShare.swift @@ -71,7 +71,7 @@ class ScreenShare: BaseViewController { let params = AgoraScreenCaptureParameters() params.frameRate = fps params.dimensions = resolution.size() - self.agoraKit.update(params) + self.agoraKit.updateScreenCaptureParameters(params) } else { self.agoraKit.setVideoEncoderConfiguration( AgoraVideoEncoderConfiguration( @@ -114,7 +114,7 @@ class ScreenShare: BaseViewController { let params = AgoraScreenCaptureParameters() params.frameRate = fps params.dimensions = resolution.size() - self.agoraKit.update(params) + self.agoraKit.updateScreenCaptureParameters(params) } else { self.agoraKit.setVideoEncoderConfiguration( AgoraVideoEncoderConfiguration( @@ -151,7 +151,7 @@ class ScreenShare: BaseViewController { } guard let displayHint = self.selectedDisplayHint else { return } print("setScreenCapture") - self.agoraKit.setScreenCapture(displayHint) + self.agoraKit.setScreenCaptureContentHint(displayHint) } } @@ -203,7 +203,8 @@ class ScreenShare: BaseViewController { let params = AgoraScreenCaptureParameters() params.frameRate = fps params.dimensions = resolution.size() - let result = agoraKit.startScreenCapture(byDisplayId: UInt(screen.sourceId), rectangle: .zero, parameters: params) + let result = agoraKit.startScreenCaptureByDisplayId(UInt(screen.sourceId), rectangle: .zero, parameters: params) + if result != 0 { // Usually happens with invalid parameters // Error code description can be found at: @@ -261,7 +262,7 @@ class ScreenShare: BaseViewController { let params = AgoraScreenCaptureParameters() params.frameRate = fps params.dimensions = resolution.size() - let result = agoraKit.startScreenCapture(byWindowId: UInt(window.id), rectangle: .zero, parameters: params) + let result = agoraKit.startScreenCaptureByWindowId(UInt(window.id), rectangle: .zero, parameters: params) if result != 0 { // Usually happens with invalid parameters // Error code description can be found at: From ef5431258d70d036819dd15d9aef43afb6f0e990 Mon Sep 17 00:00:00 2001 From: xianing Date: Fri, 3 Dec 2021 02:48:30 +0800 Subject: [PATCH 04/13] adapt 3.6.0 for windows --- .../MultiChannel/CAgoraMultiChannelDlg.h | 2 +- .../RTMPStream/AgoraRtmpStreaming.cpp | 157 +++++++----------- .../Advanced/RTMPStream/AgoraRtmpStreaming.h | 35 +--- 3 files changed, 60 insertions(+), 134 deletions(-) diff --git a/windows/APIExample/APIExample/Advanced/MultiChannel/CAgoraMultiChannelDlg.h b/windows/APIExample/APIExample/Advanced/MultiChannel/CAgoraMultiChannelDlg.h index 672597a86..6c3f15f93 100644 --- a/windows/APIExample/APIExample/Advanced/MultiChannel/CAgoraMultiChannelDlg.h +++ b/windows/APIExample/APIExample/Advanced/MultiChannel/CAgoraMultiChannelDlg.h @@ -455,7 +455,7 @@ class ChannelEventHandler :public agora::rtc::IChannelEventHandler @param state The RTMP streaming state. See: #RTMP_STREAM_PUBLISH_STATE. @param errCode The detailed error information for streaming. See: #RTMP_STREAM_PUBLISH_ERROR. */ - virtual void onRtmpStreamingStateChanged(IChannel *rtcChannel, const char *url, RTMP_STREAM_PUBLISH_STATE state, RTMP_STREAM_PUBLISH_ERROR errCode) { + virtual void onRtmpStreamingStateChanged(IChannel *rtcChannel, const char *url, RTMP_STREAM_PUBLISH_STATE state, RTMP_STREAM_PUBLISH_ERROR_TYPE errCode) { } diff --git a/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.cpp b/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.cpp index 3fde38325..d0650344b 100644 --- a/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.cpp +++ b/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.cpp @@ -89,7 +89,7 @@ void CAgoraRtmpStreamingDlgRtcEngineEventHandler::onUserOffline(uid_t uid, USER_ @param state The RTMP streaming state. See: #RTMP_STREAM_PUBLISH_STATE. @param errCode The detailed error information for streaming. See: #RTMP_STREAM_PUBLISH_ERROR. */ -void CAgoraRtmpStreamingDlgRtcEngineEventHandler::onRtmpStreamingStateChanged(const char *url, RTMP_STREAM_PUBLISH_STATE state, RTMP_STREAM_PUBLISH_ERROR errCode) +void CAgoraRtmpStreamingDlgRtcEngineEventHandler::onRtmpStreamingStateChanged(const char *url, RTMP_STREAM_PUBLISH_STATE state, RTMP_STREAM_PUBLISH_ERROR_TYPE errCode) { if (m_hMsgHanlder) { PRtmpStreamStreamStateChanged rtmpState = new RtmpStreamStreamStateChanged; @@ -116,31 +116,6 @@ void CAgoraRtmpStreamingDlgRtcEngineEventHandler::onRtmpStreamingEvent(const cha } } - - -void CAgoraRtmpStreamingDlgRtcEngineEventHandler::onStreamUnpublished(const char *url) -{ - if (m_hMsgHanlder) { - PStreamPublished streamPublished = new StreamPublished; - int len = strlen(url); - char* publishUrl = new char[len + 1]; - memset(publishUrl, 0, sizeof(publishUrl)); - strcpy_s(publishUrl, len, url); - ::PostMessage(m_hMsgHanlder, WM_MSGID(EID_RTMP_STREAM_STATE_UNPUBLISHED), (WPARAM)streamPublished, 0); - } -} - -void CAgoraRtmpStreamingDlgRtcEngineEventHandler::onStreamPublished(const char *url, int error) -{ - if (m_hMsgHanlder) { - int len = strlen(url); - char* publishUrl = new char[len + 1]; - memset(publishUrl, 0, sizeof(publishUrl)); - strcpy_s(publishUrl, len, url); - ::PostMessage(m_hMsgHanlder, WM_MSGID(EID_RTMP_STREAM_STATE_PUBLISHED), (WPARAM)publishUrl, error); - } -} - IMPLEMENT_DYNAMIC(CAgoraRtmpStreamingDlg, CDialogEx) CAgoraRtmpStreamingDlg::CAgoraRtmpStreamingDlg(CWnd* pParent /*=nullptr*/) @@ -182,8 +157,6 @@ BEGIN_MESSAGE_MAP(CAgoraRtmpStreamingDlg, CDialogEx) ON_MESSAGE(WM_MSGID(EID_RTMP_STREAM_STATE_CHANGED), &CAgoraRtmpStreamingDlg::OnEIDRtmpStateChanged) ON_MESSAGE(WM_MSGID(EID_USER_JOINED), &CAgoraRtmpStreamingDlg::OnEIDUserJoined) ON_MESSAGE(WM_MSGID(EID_USER_OFFLINE), &CAgoraRtmpStreamingDlg::OnEIDUserOffline) - ON_MESSAGE(WM_MSGID(EID_RTMP_STREAM_STATE_PUBLISHED), &CAgoraRtmpStreamingDlg::OnEIDStreamPublished) - ON_MESSAGE(WM_MSGID(EID_RTMP_STREAM_STATE_UNPUBLISHED), &CAgoraRtmpStreamingDlg::OnEIDStreamUnpublished) ON_BN_CLICKED(IDC_BUTTON_JOINCHANNEL, &CAgoraRtmpStreamingDlg::OnBnClickedButtonJoinchannel) ON_BN_CLICKED(IDC_BUTTON_ADDSTREAM, &CAgoraRtmpStreamingDlg::OnBnClickedButtonAddstream) ON_BN_CLICKED(IDC_BUTTON_REMOVE_STREAM, &CAgoraRtmpStreamingDlg::OnBnClickedButtonRemoveStream) @@ -316,7 +289,7 @@ void CAgoraRtmpStreamingDlg::RemoveAllRtmpUrls() for (int i = 0; i < m_cmbRtmpUrl.GetCount(); ++i) { m_cmbRtmpUrl.GetLBText(i, strUrl); std::string szUrl = cs2utf8(strUrl); - m_rtcEngine->removePublishStreamUrl(szUrl.c_str()); + m_rtcEngine->stopRtmpStream(szUrl.c_str()); } m_cmbRtmpUrl.Clear(); m_cmbRtmpUrl.ResetContent(); @@ -393,7 +366,14 @@ void CAgoraRtmpStreamingDlg::OnBnClickedButtonAddstream() std::string szURL = cs2utf8(strURL); BOOL isTransCoding = m_chkTransCoding.GetCheck(); // add publish stream in the engine. - int ret = m_rtcEngine->addPublishStreamUrl(szURL.c_str(), isTransCoding); + int ret; + + if (isTransCoding) { + ret = m_rtcEngine->startRtmpStreamWithTranscoding(szURL.c_str(), m_liveTransCoding); + } + else { + ret = m_rtcEngine->startRtmpStreamWithoutTranscoding(szURL.c_str()); + } if (ret != 0) { CString strInfo; @@ -417,7 +397,7 @@ void CAgoraRtmpStreamingDlg::OnBnClickedButtonRemoveStream() m_cmbRtmpUrl.GetWindowText(strUrl); std::string szUrl = cs2utf8(strUrl); //remove publish stream in the engine. - m_rtcEngine->removePublishStreamUrl(szUrl.c_str()); + m_rtcEngine->stopRtmpStream(szUrl.c_str()); } //remove all streams in the engine. @@ -434,7 +414,7 @@ void CAgoraRtmpStreamingDlg::OnBnClickedButtonRemoveAllstream() std::string szUrl = cs2utf8(strUrl); //remove public stream in the engine. - m_rtcEngine->removePublishStreamUrl(szUrl.c_str()); + m_rtcEngine->stopRtmpStream(szUrl.c_str()); m_btnRemoveStream.EnableWindow(FALSE); } @@ -479,7 +459,7 @@ LRESULT CAgoraRtmpStreamingDlg::OnEIDUserJoined(WPARAM wParam, LPARAM lParam) //add user info to TranscodingUsers. m_liveTransCoding.transcodingUsers = p; //set current live trans coding. - m_rtcEngine->setLiveTranscoding(m_liveTransCoding); + m_rtcEngine->updateRtmpTranscoding(m_liveTransCoding); return TRUE; } @@ -505,7 +485,7 @@ LRESULT CAgoraRtmpStreamingDlg::OnEIDUserOffline(WPARAM wParam, LPARAM lParam) m_liveTransCoding.transcodingUsers[i].width = width; } //set current live trans coding. - m_rtcEngine->setLiveTranscoding(m_liveTransCoding); + m_rtcEngine->updateRtmpTranscoding(m_liveTransCoding); return TRUE; } @@ -584,6 +564,49 @@ LRESULT CAgoraRtmpStreamingDlg::OnEIDRtmpStateChanged(WPARAM wParam, LPARAM lPar break; case RTMP_STREAM_PUBLISH_STATE_FAILURE: { + strInfo = agoraRtmpStateRunningSuccess; + CString strUrl; + strUrl.Format(_T("%S"), rtmpState->url); + std::string szUrl = cs2utf8(strUrl); + m_rtcEngine->stopRtmpStream(szUrl.c_str()); + + int error = lParam; + if (error == RTMP_STREAM_PUBLISH_ERROR_CONNECTION_TIMEOUT + || error == RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR + || error == RTMP_STREAM_PUBLISH_ERROR_STREAM_NOT_FOUND + || error == RTMP_STREAM_PUBLISH_ERROR_NET_DOWN) { + + m_mapRemoveFlag[szUrl.c_str()] = false; + m_mapRepublishFlag[szUrl.c_str()] = true; + CString strUrl; + strUrl.Format(_T("%S"), szUrl.c_str()); + for (int i = 0; i < m_cmbRtmpUrl.GetCount(); ++i) { + CString strText; + m_cmbRtmpUrl.GetLBText(i, strText); + if (strText.Compare(strUrl) == 0) { + m_cmbRtmpUrl.DeleteString(i); + break; + } + } + + if (m_urlSet.find(strUrl) != m_urlSet.end()) { + m_urlSet.erase(strUrl); + } + + if (m_cmbRtmpUrl.GetCurSel() < 0 && m_cmbRtmpUrl.GetCount() > 0) + m_cmbRtmpUrl.SetCurSel(0); + } + else { + if (m_mapRepublishFlag.find(szUrl.c_str()) != m_mapRepublishFlag.end() + && m_mapRemoveFlag.find(szUrl.c_str()) != m_mapRemoveFlag.end()) { + if (m_mapRepublishFlag[szUrl.c_str()] + && !m_mapRemoveFlag[szUrl.c_str()]) {//republish, removePublish when error + m_rtcEngine->startRtmpStreamWithoutTranscoding(szUrl.c_str()); + } + } + } + + switch (rtmpState->state) { case RTMP_STREAM_PUBLISH_ERROR_INVALID_ARGUMENT: @@ -700,70 +723,6 @@ LRESULT CAgoraRtmpStreamingDlg::OnEIDRtmpEvent(WPARAM wParam, LPARAM lParam) return 0; } -LRESULT CAgoraRtmpStreamingDlg::OnEIDStreamUnpublished(WPARAM wParam, LPARAM lParam) -{ - char* url = (char*)wParam; - - if (m_mapRepublishFlag.find(url) != m_mapRepublishFlag.end() - && m_mapRemoveFlag.find(url) != m_mapRemoveFlag.end()) { - if (m_mapRepublishFlag[url] - && !m_mapRemoveFlag[url]) {//republish, removePublish when error - m_rtcEngine->addPublishStreamUrl(url, false); - } - } - - delete[] url; - url = nullptr; - return 0; -} - -LRESULT CAgoraRtmpStreamingDlg::OnEIDStreamPublished(WPARAM wParam, LPARAM lParam) -{ - char* url = (char*)wParam; - int error = lParam; - - if (error == 1 || error == 10 || error == 154) { - m_mapRemoveFlag[url] = false; - m_rtcEngine->removePublishStreamUrl(url); - m_mapRepublishFlag[url] = true; - CString strUrl; - strUrl.Format(_T("%S"), url); - for (int i = 0; i < m_cmbRtmpUrl.GetCount(); ++i) { - CString strText; - m_cmbRtmpUrl.GetLBText(i, strText); - if (strText.Compare(strUrl) == 0) { - m_cmbRtmpUrl.DeleteString(i); - break; - } - } - - if (m_urlSet.find(strUrl) != m_urlSet.end()) { - m_urlSet.erase(strUrl); - } - - if (m_cmbRtmpUrl.GetCurSel() < 0 && m_cmbRtmpUrl.GetCount() > 0) - m_cmbRtmpUrl.SetCurSel(0); - } - else if (error == 155) { - m_rtcEngine->addPublishStreamUrl(url, false); - - if (m_mapUrlToTimer.find(url) == m_mapUrlToTimer.end()) { - LastTimer_Republish_id++; - m_mapUrlToTimer[url] = LastTimer_Republish_id; - m_mapTimerToUrl[LastTimer_Republish_id] = url; - m_mapTimerToRepublishCount[LastTimer_Republish_id] = 1; - - SetTimer(LastTimer_Republish_id, 1000, NULL); - } - - } - - - delete[] url; - url = nullptr; - return 0; -} - void CAgoraRtmpStreamingDlg::OnTimer(UINT_PTR nIDEvent) { @@ -778,6 +737,6 @@ void CAgoraRtmpStreamingDlg::OnTimer(UINT_PTR nIDEvent) } m_mapTimerToRepublishCount[nIDEvent]++; - m_rtcEngine->addPublishStreamUrl(m_mapTimerToUrl[nIDEvent].c_str(), false); + m_rtcEngine->startRtmpStreamWithoutTranscoding(m_mapTimerToUrl[nIDEvent].c_str()); } } \ No newline at end of file diff --git a/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.h b/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.h index 823adb9c7..b7299fc7f 100644 --- a/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.h +++ b/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.h @@ -71,38 +71,7 @@ class CAgoraRtmpStreamingDlgRtcEngineEventHandler @param state The RTMP streaming state. See: #RTMP_STREAM_PUBLISH_STATE. @param errCode The detailed error information for streaming. See: #RTMP_STREAM_PUBLISH_ERROR. */ - virtual void onRtmpStreamingStateChanged(const char *url, RTMP_STREAM_PUBLISH_STATE state, RTMP_STREAM_PUBLISH_ERROR errCode)override; - - /** @deprecated This method is deprecated, use the \ref agora::rtc::IRtcEngineEventHandler::onRtmpStreamingStateChanged "onRtmpStreamingStateChanged" callback instead. - - Reports the result of calling the \ref agora::rtc::IRtcEngine::removePublishStreamUrl "removePublishStreamUrl" method. (CDN live only.) - - This callback indicates whether you have successfully removed an RTMP stream from the CDN. - - @param url The RTMP URL address. - */ - virtual void onStreamUnpublished(const char *url) override; - - /** @deprecated This method is deprecated, use the \ref agora::rtc::IRtcEngineEventHandler::onRtmpStreamingStateChanged "onRtmpStreamingStateChanged" callback instead. - - Reports the result of calling the \ref IRtcEngine::addPublishStreamUrl "addPublishStreamUrl" method. (CDN live only.) - - @param url The RTMP URL address. - @param error Error code: #ERROR_CODE_TYPE. Main errors include: - - #ERR_OK (0): The publishing succeeds. - - #ERR_FAILED (1): The publishing fails. - - #ERR_INVALID_ARGUMENT (2): Invalid argument used. If, for example, you did not call \ref agora::rtc::IRtcEngine::setLiveTranscoding "setLiveTranscoding" to configure LiveTranscoding before calling \ref agora::rtc::IRtcEngine::addPublishStreamUrl "addPublishStreamUrl", the SDK reports #ERR_INVALID_ARGUMENT. - - #ERR_TIMEDOUT (10): The publishing timed out. - - #ERR_ALREADY_IN_USE (19): The chosen URL address is already in use for CDN live streaming. - - #ERR_RESOURCE_LIMITED (22): The backend system does not have enough resources for the CDN live streaming. - - #ERR_ENCRYPTED_STREAM_NOT_ALLOWED_PUBLISH (130): You cannot publish an encrypted stream. - - #ERR_PUBLISH_STREAM_CDN_ERROR (151) - - #ERR_PUBLISH_STREAM_NUM_REACH_LIMIT (152) - - #ERR_PUBLISH_STREAM_NOT_AUTHORIZED (153) - - #ERR_PUBLISH_STREAM_INTERNAL_SERVER_ERROR (154) - - #ERR_PUBLISH_STREAM_FORMAT_NOT_SUPPORTED (156) - */ - virtual void onStreamPublished(const char *url, int error) override; + virtual void onRtmpStreamingStateChanged(const char *url, RTMP_STREAM_PUBLISH_STATE state, RTMP_STREAM_PUBLISH_ERROR_TYPE errType)override; virtual void onRtmpStreamingEvent(const char* url, RTMP_STREAMING_EVENT eventCode)override; private: @@ -169,8 +138,6 @@ class CAgoraRtmpStreamingDlg : public CDialogEx afx_msg LRESULT OnEIDLeaveChannel(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnEIDRtmpStateChanged(WPARAM wParam, LPARAM lParam); afx_msg void OnSelchangeListInfoBroadcasting(); - afx_msg LRESULT OnEIDStreamUnpublished(WPARAM wParam, LPARAM lParam); - afx_msg LRESULT OnEIDStreamPublished(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnEIDRtmpEvent(WPARAM wParam, LPARAM lParam); afx_msg void OnTimer(UINT_PTR nIDEvent); From 197258085e1a5a43dd22364dc962ed7d7022c957 Mon Sep 17 00:00:00 2001 From: xianing Date: Fri, 3 Dec 2021 03:02:15 +0800 Subject: [PATCH 05/13] fix macos rtmp issues --- .../RTMPStreaming/RTMPStreaming.swift | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift b/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift index ef81f9e17..9a53ca1fc 100644 --- a/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift +++ b/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift @@ -20,6 +20,7 @@ class RTMPStreaming: BaseViewController { var agoraKit: AgoraRtcEngineKit! var transcoding = AgoraLiveTranscoding.default() + var unpublishing = false /** --- rtmpUrls Picker --- @@ -43,7 +44,8 @@ class RTMPStreaming: BaseViewController { /// callback when remove streaming url button hit @IBAction func onRemoveStreamingURL(_ sender: Any) { guard let selectedURL = selectedrtmpUrl else { return } - agoraKit.removePublishStreamUrl(selectedURL) + agoraKit.stopRtmpStream(selectedURL) + unpublishing = true rtmpURLs.remove(at: selectRtmpUrlsPicker.indexOfSelectedItem) selectRtmpUrlsPicker.picker.removeItem(at: selectRtmpUrlsPicker.indexOfSelectedItem) } @@ -51,10 +53,11 @@ class RTMPStreaming: BaseViewController { /// callback when remove all streaming url button hit @IBAction func onRemoveAllStreamingURL(_ sender: Any) { for url in rtmpURLs { - agoraKit.removePublishStreamUrl(url) + agoraKit.stopRtmpStream(url) } rtmpURLs = [] selectRtmpUrlsPicker.picker.removeAllItems() + unpublishing = true } /** @@ -345,9 +348,28 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { if(state == .running) { self.showAlert(title: "Notice", message: "\(url) Publish Success") } else if(state == .failure) { - self.showAlert(title: "Error", message: "\(url) Publish Failed: \(errorCode.rawValue)") + agoraKit.stopRtmpStream(url) + if errorCode == .streamingErrorCodeInternalServerError + || errorCode == .streamingErrorCodeStreamNotFound + || errorCode == .streamPublishErrorNetDown + || errorCode == .streamingErrorCodeConnectionTimeout { + self.showAlert(title: "Error", message: "\(url) Publish Failed: \(errorCode.rawValue)") + unpublishing = true + } } else if(state == .idle) { self.showAlert(title: "Notice", message: "\(url) Publish Stopped") + if !unpublishing { + // start publishing to this URL + if transcodingEnabled { + agoraKit.startRtmpStreamWithTranscoding(url, transcoding: transcoding) + } + else { + agoraKit.startRtmpStreamWithoutTranscoding(url) + } + } + else { + unpublishing = false + } } } From 2f36d30496385af5b1ab6770295c0e9a4295af46 Mon Sep 17 00:00:00 2001 From: xianing Date: Fri, 3 Dec 2021 12:28:34 +0800 Subject: [PATCH 06/13] adjust rtmp error code handling --- .../examples/advanced/RTMPStreaming.java | 8 ++++++- .../RTMPStreaming/RTMPStreaming.swift | 3 +++ .../RTMPStreaming/RTMPStreaming.swift | 3 +++ .../RTMPStream/AgoraRtmpStreaming.cpp | 24 ++++++++++--------- 4 files changed, 26 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 db2d94a22..6b3bc030a 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 @@ -44,6 +44,7 @@ import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR; import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_NET_DOWN; import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_OK; +import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_RTMP_SERVER_ERROR; import static io.agora.rtc.Constants.RTMP_STREAM_PUBLISH_ERROR_STREAM_NOT_FOUND; import static io.agora.rtc.video.VideoCanvas.RENDER_MODE_HIDDEN; import static io.agora.rtc.video.VideoEncoderConfiguration.STANDARD_BITRATE; @@ -528,10 +529,15 @@ public void onRtmpStreamingStateChanged(String url, int state, int errorType) { engine.stopRtmpStream(et_url.getText().toString()); if((errorType == RTMP_STREAM_PUBLISH_ERROR_CONNECTION_TIMEOUT || errorType == RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR + || errorType == RTMP_STREAM_PUBLISH_ERROR_RTMP_SERVER_ERROR || errorType == RTMP_STREAM_PUBLISH_ERROR_STREAM_NOT_FOUND || errorType == RTMP_STREAM_PUBLISH_ERROR_NET_DOWN)) { - /**if failed, make changes to the UI.*/ + /**need republishing.*/ + Log.w(TAG, "RTMP publish failure ->" + url + ", state->" + state + ", errorType->" + errorType); + } + else{ + /**Other failures which can't be recover by republishing, make changes to the UI.*/ retryTask.cancel(true); unpublishing = true; } diff --git a/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift b/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift index 558fdd3e5..772c11d5c 100644 --- a/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift +++ b/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift @@ -334,8 +334,11 @@ extension RTMPStreamingMain: AgoraRtcEngineDelegate { if errorCode == .streamingErrorCodeInternalServerError || errorCode == .streamingErrorCodeStreamNotFound || errorCode == .streamPublishErrorNetDown + || errorCode == .streamingErrorCodeRtmpServerError || errorCode == .streamingErrorCodeConnectionTimeout { self.showAlert(title: "Error", message: "RTMP Publish Failed: \(errorCode.rawValue)") + } + else{ stopRetryTimer() unpublishing = true } diff --git a/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift b/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift index 9a53ca1fc..7731286a4 100644 --- a/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift +++ b/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift @@ -352,8 +352,11 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { if errorCode == .streamingErrorCodeInternalServerError || errorCode == .streamingErrorCodeStreamNotFound || errorCode == .streamPublishErrorNetDown + || errorCode == .streamingErrorCodeRtmpServerError || errorCode == .streamingErrorCodeConnectionTimeout { self.showAlert(title: "Error", message: "\(url) Publish Failed: \(errorCode.rawValue)") + } + else{ unpublishing = true } } else if(state == .idle) { diff --git a/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.cpp b/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.cpp index d0650344b..46cb6ed7d 100644 --- a/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.cpp +++ b/windows/APIExample/APIExample/Advanced/RTMPStream/AgoraRtmpStreaming.cpp @@ -513,7 +513,7 @@ LRESULT CAgoraRtmpStreamingDlg::OnEIDRtmpStateChanged(WPARAM wParam, LPARAM lPar { case RTMP_STREAM_PUBLISH_STATE_IDLE: { - strInfo.Format(_T("%s:%S"), agoraRtmpStateIdle, rtmpState->url); + strInfo.Format(_T("%s:%S��"), agoraRtmpStateIdle, rtmpState->url); CString strUrl; strUrl.Format(_T("%S"), rtmpState->url); int sel = m_cmbRtmpUrl.GetCurSel(); @@ -574,8 +574,19 @@ LRESULT CAgoraRtmpStreamingDlg::OnEIDRtmpStateChanged(WPARAM wParam, LPARAM lPar if (error == RTMP_STREAM_PUBLISH_ERROR_CONNECTION_TIMEOUT || error == RTMP_STREAM_PUBLISH_ERROR_INTERNAL_SERVER_ERROR || error == RTMP_STREAM_PUBLISH_ERROR_STREAM_NOT_FOUND + || error == RTMP_STREAM_PUBLISH_ERROR_RTMP_SERVER_ERROR || error == RTMP_STREAM_PUBLISH_ERROR_NET_DOWN) { - + if (m_mapRepublishFlag.find(szUrl.c_str()) != m_mapRepublishFlag.end() + && m_mapRemoveFlag.find(szUrl.c_str()) != m_mapRemoveFlag.end()) { + if (m_mapRepublishFlag[szUrl.c_str()] + && !m_mapRemoveFlag[szUrl.c_str()]) { + //republish, removePublish when error + m_rtcEngine->startRtmpStreamWithoutTranscoding(szUrl.c_str()); + } + } + } + else { + // stop retrying m_mapRemoveFlag[szUrl.c_str()] = false; m_mapRepublishFlag[szUrl.c_str()] = true; CString strUrl; @@ -596,15 +607,6 @@ LRESULT CAgoraRtmpStreamingDlg::OnEIDRtmpStateChanged(WPARAM wParam, LPARAM lPar if (m_cmbRtmpUrl.GetCurSel() < 0 && m_cmbRtmpUrl.GetCount() > 0) m_cmbRtmpUrl.SetCurSel(0); } - else { - if (m_mapRepublishFlag.find(szUrl.c_str()) != m_mapRepublishFlag.end() - && m_mapRemoveFlag.find(szUrl.c_str()) != m_mapRemoveFlag.end()) { - if (m_mapRepublishFlag[szUrl.c_str()] - && !m_mapRemoveFlag[szUrl.c_str()]) {//republish, removePublish when error - m_rtcEngine->startRtmpStreamWithoutTranscoding(szUrl.c_str()); - } - } - } switch (rtmpState->state) From 2e54cffdaa37244c9f63f8fb1627557eaf4e81a8 Mon Sep 17 00:00:00 2001 From: xianing Date: Mon, 6 Dec 2021 13:12:30 +0800 Subject: [PATCH 07/13] fix macos setting issue --- macOS/APIExample/SettingsController.swift | 4 ---- macOS/APIExample/ViewController.swift | 7 ++++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/macOS/APIExample/SettingsController.swift b/macOS/APIExample/SettingsController.swift index 643a0d099..86e4f6f01 100644 --- a/macOS/APIExample/SettingsController.swift +++ b/macOS/APIExample/SettingsController.swift @@ -33,10 +33,6 @@ class SettingsController: BaseViewController { self.fpsPicker.addItems(withTitles: GlobalSettings.shared.fpsSetting.options.map { $0.label }) self.fpsPicker.selectItem(at: GlobalSettings.shared.fpsSetting.selected) - self.proxyLabel.cell?.title = "Enable Cloud Proxy".localized - self.proxyPicker.addItems(withTitles: GlobalSettings.shared.proxySetting.options.map { $0.label }) - self.proxyPicker.selectItem(at: GlobalSettings.shared.proxySetting.selected) - self.sdkVersion.cell?.title = "v\(AgoraRtcEngineKit.getSdkVersion())" } diff --git a/macOS/APIExample/ViewController.swift b/macOS/APIExample/ViewController.swift index b083a09d5..d57fbdea3 100644 --- a/macOS/APIExample/ViewController.swift +++ b/macOS/APIExample/ViewController.swift @@ -37,9 +37,9 @@ class MenuController: NSViewController { MenuItem(name: "Media Channel Relay".localized, identifier: "menuCell", controller: "ChannelMediaRelay", storyboard: "ChannelMediaRelay"), MenuItem(name: "Audio Mixing".localized, identifier: "menuCell", controller: "AudioMixing", storyboard: "AudioMixing"), MenuItem(name: "Voice Changer".localized, identifier: "menuCell", controller: "VoiceChanger", storyboard: "VoiceChanger"), - MenuItem(name: "Precall Test".localized, identifier: "menuCell", controller: "PrecallTest", storyboard: "PrecallTest"), MenuItem(name: "Create Data Stream".localized, identifier: "menuCell", controller: "CreateDataStream", storyboard: "CreateDataStream"), - MenuItem(name: "Raw Audio Data".localized, identifier: "menuCell", controller: "RawAudioData", storyboard: "RawAudioData") + MenuItem(name: "Raw Audio Data".localized, identifier: "menuCell", controller: "RawAudioData", storyboard: "RawAudioData"), + MenuItem(name: "Precall Test".localized, identifier: "menuCell", controller: "PrecallTest", storyboard: "PrecallTest") ] @IBOutlet weak var tableView:NSTableView! @@ -109,9 +109,11 @@ extension MenuController: NSTableViewDataSource, NSTableViewDelegate { func tableViewSelectionDidChange(_ notification: Notification) { if tableView.selectedRow >= 0 && tableView.selectedRow < menus.count { + Thread.sleep(forTimeInterval: 1) loadSplitViewItem(item: menus[tableView.selectedRow]) } } + } class ViewController: NSViewController { @@ -128,4 +130,3 @@ class ViewController: NSViewController { } } } - From 820011cc95a911793c6b388394c013b5f8ac95ae Mon Sep 17 00:00:00 2001 From: xianing Date: Tue, 7 Dec 2021 16:19:55 +0800 Subject: [PATCH 08/13] adapt latest sdk changes --- .../JoinMultiChannel/JoinMultiChannel.swift | 8 ++++---- .../Advanced/RTMPStreaming/RTMPStreaming.swift | 2 +- .../JoinMultiChannel/JoinMultiChannel.swift | 18 +++++++++--------- .../Advanced/RTMPStreaming/RTMPStreaming.swift | 4 ++-- .../Advanced/ScreenShare/ScreenShare.swift | 10 +++++----- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/iOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift b/iOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift index e772d0bdb..635510bd2 100644 --- a/iOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift +++ b/iOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift @@ -184,7 +184,7 @@ extension JoinMultiChannelMain: AgoraRtcEngineDelegate { extension JoinMultiChannelMain: AgoraRtcChannelDelegate { func rtcChannelDidJoin(_ rtcChannel: AgoraRtcChannel, withUid uid: UInt, elapsed: Int) { - LogUtils.log(message: "Join \(rtcChannel.getChannelId() ?? "") with uid \(uid) elapsed \(elapsed)ms", level: .info) + LogUtils.log(message: "Join \(rtcChannel.getId() ?? "") with uid \(uid) elapsed \(elapsed)ms", level: .info) } /// callback when warning occured for a channel, warning can usually be ignored, still it's nice to check out /// what is happening @@ -193,7 +193,7 @@ extension JoinMultiChannelMain: AgoraRtcChannelDelegate /// cn: https://docs.agora.io/cn/Voice/API%20Reference/oc/Constants/AgoraWarningCode.html /// @param warningCode warning code of the problem func rtcChannel(_ rtcChannel: AgoraRtcChannel, didOccurWarning warningCode: AgoraWarningCode) { - LogUtils.log(message: "channel: \(rtcChannel.getChannelId() ?? ""), warning: \(warningCode.description)", level: .warning) + LogUtils.log(message: "channel: \(rtcChannel.getId() ?? ""), warning: \(warningCode.description)", level: .warning) } /// callback when error occured for a channel, you are recommended to display the error descriptions on demand @@ -222,7 +222,7 @@ extension JoinMultiChannelMain: AgoraRtcChannelDelegate videoCanvas.view = channel1 == rtcChannel ? channel1RemoteVideo.videoView : channel2RemoteVideo.videoView videoCanvas.renderMode = .hidden // set channelId so that it knows which channel the video belongs to - videoCanvas.channelId = rtcChannel.getChannelId() + videoCanvas.channelId = rtcChannel.getId() agoraKit.setupRemoteVideo(videoCanvas) } @@ -242,7 +242,7 @@ extension JoinMultiChannelMain: AgoraRtcChannelDelegate videoCanvas.view = nil videoCanvas.renderMode = .hidden // set channelId so that it knows which channel the video belongs to - videoCanvas.channelId = rtcChannel.getChannelId() + videoCanvas.channelId = rtcChannel.getId() agoraKit.setupRemoteVideo(videoCanvas) } } diff --git a/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift b/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift index 772c11d5c..7d48f0318 100644 --- a/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift +++ b/iOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift @@ -180,7 +180,7 @@ class RTMPStreamingMain: BaseViewController { // therefore we have to create a livetranscoding object and call before addPublishStreamUrl transcoding.size = CGSize(width: CANVAS_WIDTH, height: CANVAS_HEIGHT) agoraKit.setLiveTranscoding(transcoding) - agoraKit.startRtmpStreamWithTranscoding(rtmpURL, transcoding: transcoding) + agoraKit.startRtmpStream(withTranscoding: rtmpURL, transcoding: transcoding) } else{ agoraKit.startRtmpStreamWithoutTranscoding(rtmpURL) diff --git a/macOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift b/macOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift index 0a675a3f8..fc966250b 100644 --- a/macOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift +++ b/macOS/APIExample/Examples/Advanced/JoinMultiChannel/JoinMultiChannel.swift @@ -75,7 +75,7 @@ class JoinMultipleChannel: BaseViewController { } } else { channel1?.leave() - if let channelName = channel1?.getChannelId() { + if let channelName = channel1?.getId() { if isPublished && channelName == selectedChannel { if let channel = getChannelByName(selectedChannel) { channel.setClientRole(.audience) @@ -147,7 +147,7 @@ class JoinMultipleChannel: BaseViewController { } } else { channel2?.leave() - if let channelName = channel2?.getChannelId() { + if let channelName = channel2?.getId() { if isPublished && channelName == selectedChannel { if let channel = getChannelByName(selectedChannel) { channel.setClientRole(.audience) @@ -258,9 +258,9 @@ class JoinMultipleChannel: BaseViewController { } func getChannelByName(_ channelName: String?) -> AgoraRtcChannel? { - if channel1?.getChannelId() == channelName { + if channel1?.getId() == channelName { return channel1 - } else if channel2?.getChannelId() == channelName { + } else if channel2?.getId() == channelName { return channel2 } return nil @@ -305,8 +305,8 @@ extension JoinMultipleChannel: AgoraRtcEngineDelegate { extension JoinMultipleChannel: AgoraRtcChannelDelegate { func rtcChannelDidJoin(_ rtcChannel: AgoraRtcChannel, withUid uid: UInt, elapsed: Int) { - LogUtils.log(message: "Join \(rtcChannel.getChannelId() ?? "") with uid \(uid) elapsed \(elapsed)ms", level: .info) - selectChannelsPicker.picker.addItem(withTitle: rtcChannel.getChannelId()!) + LogUtils.log(message: "Join \(rtcChannel.getId() ?? "") with uid \(uid) elapsed \(elapsed)ms", level: .info) + selectChannelsPicker.picker.addItem(withTitle: rtcChannel.getId()!) if (channel1 == rtcChannel) { isJoined = true } else { @@ -320,7 +320,7 @@ extension JoinMultipleChannel: AgoraRtcChannelDelegate { /// cn: https://docs.agora.io/cn/Voice/API%20Reference/oc/Constants/AgoraWarningCode.html /// @param warningCode warning code of the problem func rtcChannel(_ rtcChannel: AgoraRtcChannel, didOccurWarning warningCode: AgoraWarningCode) { - LogUtils.log(message: "channel: \(rtcChannel.getChannelId() ?? ""), warning: \(warningCode.rawValue)", level: .warning) + LogUtils.log(message: "channel: \(rtcChannel.getId() ?? ""), warning: \(warningCode.rawValue)", level: .warning) } /// callback when error occured for a channel, you are recommended to display the error descriptions on demand @@ -349,7 +349,7 @@ extension JoinMultipleChannel: AgoraRtcChannelDelegate { videoCanvas.view = channel1 == rtcChannel ? videos2[0].videocanvas : videos2[1].videocanvas videoCanvas.renderMode = .hidden // set channelId so that it knows which channel the video belongs to - videoCanvas.channelId = rtcChannel.getChannelId() + videoCanvas.channelId = rtcChannel.getId() agoraKit.setupRemoteVideo(videoCanvas) } @@ -369,7 +369,7 @@ extension JoinMultipleChannel: AgoraRtcChannelDelegate { videoCanvas.view = nil videoCanvas.renderMode = .hidden // set channelId so that it knows which channel the video belongs to - videoCanvas.channelId = rtcChannel.getChannelId() + videoCanvas.channelId = rtcChannel.getId() agoraKit.setupRemoteVideo(videoCanvas) } } diff --git a/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift b/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift index 7731286a4..0fc2ece9a 100644 --- a/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift +++ b/macOS/APIExample/Examples/Advanced/RTMPStreaming/RTMPStreaming.swift @@ -102,7 +102,7 @@ class RTMPStreaming: BaseViewController { // start publishing to this URL if transcodingEnabled { - agoraKit.startRtmpStreamWithTranscoding(rtmpURL, transcoding: transcoding) + agoraKit.startRtmpStream(withTranscoding: rtmpURL, transcoding: transcoding) } else { agoraKit.startRtmpStreamWithoutTranscoding(rtmpURL) @@ -364,7 +364,7 @@ extension RTMPStreaming: AgoraRtcEngineDelegate { if !unpublishing { // start publishing to this URL if transcodingEnabled { - agoraKit.startRtmpStreamWithTranscoding(url, transcoding: transcoding) + agoraKit.startRtmpStream(withTranscoding: url, transcoding: transcoding) } else { agoraKit.startRtmpStreamWithoutTranscoding(url) diff --git a/macOS/APIExample/Examples/Advanced/ScreenShare/ScreenShare.swift b/macOS/APIExample/Examples/Advanced/ScreenShare/ScreenShare.swift index a94a8935e..e1f677bba 100644 --- a/macOS/APIExample/Examples/Advanced/ScreenShare/ScreenShare.swift +++ b/macOS/APIExample/Examples/Advanced/ScreenShare/ScreenShare.swift @@ -71,7 +71,7 @@ class ScreenShare: BaseViewController { let params = AgoraScreenCaptureParameters() params.frameRate = fps params.dimensions = resolution.size() - self.agoraKit.updateScreenCaptureParameters(params) + self.agoraKit.update(params) } else { self.agoraKit.setVideoEncoderConfiguration( AgoraVideoEncoderConfiguration( @@ -114,7 +114,7 @@ class ScreenShare: BaseViewController { let params = AgoraScreenCaptureParameters() params.frameRate = fps params.dimensions = resolution.size() - self.agoraKit.updateScreenCaptureParameters(params) + self.agoraKit.update(params) } else { self.agoraKit.setVideoEncoderConfiguration( AgoraVideoEncoderConfiguration( @@ -151,7 +151,7 @@ class ScreenShare: BaseViewController { } guard let displayHint = self.selectedDisplayHint else { return } print("setScreenCapture") - self.agoraKit.setScreenCaptureContentHint(displayHint) + self.agoraKit.setScreenCapture(displayHint) } } @@ -203,7 +203,7 @@ class ScreenShare: BaseViewController { let params = AgoraScreenCaptureParameters() params.frameRate = fps params.dimensions = resolution.size() - let result = agoraKit.startScreenCaptureByDisplayId(UInt(screen.sourceId), rectangle: .zero, parameters: params) + let result = agoraKit.startScreenCapture(byDisplayId: UInt(screen.sourceId), rectangle: .zero, parameters: params) if result != 0 { // Usually happens with invalid parameters @@ -262,7 +262,7 @@ class ScreenShare: BaseViewController { let params = AgoraScreenCaptureParameters() params.frameRate = fps params.dimensions = resolution.size() - let result = agoraKit.startScreenCaptureByWindowId(UInt(window.id), rectangle: .zero, parameters: params) + let result = agoraKit.startScreenCapture(byWindowId: UInt(window.id), rectangle: .zero, parameters: params) if result != 0 { // Usually happens with invalid parameters // Error code description can be found at: From 04c0e70ac3abcd71e38f373e239e1127c6ecc438 Mon Sep 17 00:00:00 2001 From: xianing Date: Tue, 7 Dec 2021 16:29:31 +0800 Subject: [PATCH 09/13] adapt latest sdk changes --- iOS/APIExample.xcodeproj/project.pbxproj | 143 +++++------------------ 1 file changed, 27 insertions(+), 116 deletions(-) diff --git a/iOS/APIExample.xcodeproj/project.pbxproj b/iOS/APIExample.xcodeproj/project.pbxproj index 6ee8d4cad..231ae8d98 100644 --- a/iOS/APIExample.xcodeproj/project.pbxproj +++ b/iOS/APIExample.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ @@ -113,45 +113,6 @@ 8407E0942472320800AC5DE8 /* (null) in Sources */ = {isa = PBXBuildFile; }; 8B349FE32681E2CE007247F2 /* agora-logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B349FE22681E2CE007247F2 /* agora-logo.png */; }; 8B98CAA42664914D001B5454 /* AgoraAudioProcessing.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8B98CAA32664914D001B5454 /* AgoraAudioProcessing.mm */; }; - 8BAF3C5F275866880073B30E /* AgoraCore.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C51275866850073B30E /* AgoraCore.xcframework */; }; - 8BAF3C61275866880073B30E /* AgoraCIExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C52275866860073B30E /* AgoraCIExtension.xcframework */; }; - 8BAF3C63275866880073B30E /* AgoraSoundTouch.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C53275866860073B30E /* AgoraSoundTouch.xcframework */; }; - 8BAF3C65275866880073B30E /* AgoraFDKAACExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C54275866860073B30E /* AgoraFDKAACExtension.xcframework */; }; - 8BAF3C67275866880073B30E /* AgoraRtcKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C55275866860073B30E /* AgoraRtcKit.xcframework */; }; - 8BAF3C69275866880073B30E /* AgoraDav1dExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C56275866860073B30E /* AgoraDav1dExtension.xcframework */; }; - 8BAF3C6B275866880073B30E /* Agoraffmpeg.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C57275866870073B30E /* Agoraffmpeg.xcframework */; }; - 8BAF3C6D275866880073B30E /* AgoraJNDExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C58275866870073B30E /* AgoraJNDExtension.xcframework */; }; - 8BAF3C6F275866880073B30E /* AgoraVideoProcessExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C59275866870073B30E /* AgoraVideoProcessExtension.xcframework */; }; - 8BAF3C71275866880073B30E /* AgoraVideoSegmentationExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5A275866870073B30E /* AgoraVideoSegmentationExtension.xcframework */; }; - 8BAF3C73275866880073B30E /* AgoraAIDenoiseExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5B275866870073B30E /* AgoraAIDenoiseExtension.xcframework */; }; - 8BAF3C75275866880073B30E /* AgoraSuperResolutionExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5C275866880073B30E /* AgoraSuperResolutionExtension.xcframework */; }; - 8BAF3C77275866880073B30E /* AgoraFDExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5D275866880073B30E /* AgoraFDExtension.xcframework */; }; - 8BAF3C78275866980073B30E /* AgoraAIDenoiseExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5B275866870073B30E /* AgoraAIDenoiseExtension.xcframework */; }; - 8BAF3C79275866980073B30E /* AgoraAIDenoiseExtension.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5B275866870073B30E /* AgoraAIDenoiseExtension.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C7A275866980073B30E /* AgoraCIExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C52275866860073B30E /* AgoraCIExtension.xcframework */; }; - 8BAF3C7B275866980073B30E /* AgoraCIExtension.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C52275866860073B30E /* AgoraCIExtension.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C7C275866980073B30E /* AgoraCore.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C51275866850073B30E /* AgoraCore.xcframework */; }; - 8BAF3C7D275866980073B30E /* AgoraCore.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C51275866850073B30E /* AgoraCore.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C7E275866990073B30E /* AgoraDav1dExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C56275866860073B30E /* AgoraDav1dExtension.xcframework */; }; - 8BAF3C7F275866990073B30E /* AgoraDav1dExtension.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C56275866860073B30E /* AgoraDav1dExtension.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C80275866990073B30E /* AgoraFDExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5D275866880073B30E /* AgoraFDExtension.xcframework */; }; - 8BAF3C81275866990073B30E /* AgoraFDExtension.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5D275866880073B30E /* AgoraFDExtension.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C82275866990073B30E /* AgoraFDKAACExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C54275866860073B30E /* AgoraFDKAACExtension.xcframework */; }; - 8BAF3C83275866990073B30E /* AgoraFDKAACExtension.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C54275866860073B30E /* AgoraFDKAACExtension.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C84275866990073B30E /* Agoraffmpeg.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C57275866870073B30E /* Agoraffmpeg.xcframework */; }; - 8BAF3C85275866990073B30E /* Agoraffmpeg.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C57275866870073B30E /* Agoraffmpeg.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C86275866990073B30E /* AgoraJNDExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C58275866870073B30E /* AgoraJNDExtension.xcframework */; }; - 8BAF3C87275866990073B30E /* AgoraJNDExtension.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C58275866870073B30E /* AgoraJNDExtension.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C88275866990073B30E /* AgoraRtcKit.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C55275866860073B30E /* AgoraRtcKit.xcframework */; }; - 8BAF3C89275866990073B30E /* AgoraRtcKit.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C55275866860073B30E /* AgoraRtcKit.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C8A275866990073B30E /* AgoraSoundTouch.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C53275866860073B30E /* AgoraSoundTouch.xcframework */; }; - 8BAF3C8B275866990073B30E /* AgoraSoundTouch.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C53275866860073B30E /* AgoraSoundTouch.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C8C275866990073B30E /* AgoraSuperResolutionExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5C275866880073B30E /* AgoraSuperResolutionExtension.xcframework */; }; - 8BAF3C8D275866990073B30E /* AgoraSuperResolutionExtension.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5C275866880073B30E /* AgoraSuperResolutionExtension.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C8E275866990073B30E /* AgoraVideoProcessExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C59275866870073B30E /* AgoraVideoProcessExtension.xcframework */; }; - 8BAF3C8F275866990073B30E /* AgoraVideoProcessExtension.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C59275866870073B30E /* AgoraVideoProcessExtension.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8BAF3C90275866990073B30E /* AgoraVideoSegmentationExtension.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5A275866870073B30E /* AgoraVideoSegmentationExtension.xcframework */; }; - 8BAF3C91275866990073B30E /* AgoraVideoSegmentationExtension.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8BAF3C5A275866870073B30E /* AgoraVideoSegmentationExtension.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8BAF3C992758693B0073B30E /* VideoProcess.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8BAF3C942758693A0073B30E /* VideoProcess.strings */; }; 8BAF3C9A2758693B0073B30E /* VideoProcess.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BAF3C962758693A0073B30E /* VideoProcess.swift */; }; 8BAF3C9B2758693B0073B30E /* VideoProcess.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8BAF3C972758693A0073B30E /* VideoProcess.storyboard */; }; @@ -185,29 +146,6 @@ name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; }; - 8BAF3C92275866990073B30E /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 8BAF3C83275866990073B30E /* AgoraFDKAACExtension.xcframework in Embed Frameworks */, - 8BAF3C7B275866980073B30E /* AgoraCIExtension.xcframework in Embed Frameworks */, - 8BAF3C91275866990073B30E /* AgoraVideoSegmentationExtension.xcframework in Embed Frameworks */, - 8BAF3C89275866990073B30E /* AgoraRtcKit.xcframework in Embed Frameworks */, - 8BAF3C7F275866990073B30E /* AgoraDav1dExtension.xcframework in Embed Frameworks */, - 8BAF3C81275866990073B30E /* AgoraFDExtension.xcframework in Embed Frameworks */, - 8BAF3C7D275866980073B30E /* AgoraCore.xcframework in Embed Frameworks */, - 8BAF3C8D275866990073B30E /* AgoraSuperResolutionExtension.xcframework in Embed Frameworks */, - 8BAF3C79275866980073B30E /* AgoraAIDenoiseExtension.xcframework in Embed Frameworks */, - 8BAF3C85275866990073B30E /* Agoraffmpeg.xcframework in Embed Frameworks */, - 8BAF3C8B275866990073B30E /* AgoraSoundTouch.xcframework in Embed Frameworks */, - 8BAF3C8F275866990073B30E /* AgoraVideoProcessExtension.xcframework in Embed Frameworks */, - 8BAF3C87275866990073B30E /* AgoraJNDExtension.xcframework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -381,22 +319,22 @@ 8B98CAA12664914D001B5454 /* AgoraAudioProcessing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AgoraAudioProcessing.h; sourceTree = ""; }; 8B98CAA22664914D001B5454 /* AgoraAudioCriticalSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AgoraAudioCriticalSection.h; sourceTree = ""; }; 8B98CAA32664914D001B5454 /* AgoraAudioProcessing.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AgoraAudioProcessing.mm; sourceTree = ""; }; - 8BAF3C51275866850073B30E /* AgoraCore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraCore.xcframework; sourceTree = ""; }; - 8BAF3C52275866860073B30E /* AgoraCIExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraCIExtension.xcframework; sourceTree = ""; }; - 8BAF3C53275866860073B30E /* AgoraSoundTouch.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraSoundTouch.xcframework; sourceTree = ""; }; - 8BAF3C54275866860073B30E /* AgoraFDKAACExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraFDKAACExtension.xcframework; sourceTree = ""; }; - 8BAF3C55275866860073B30E /* AgoraRtcKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraRtcKit.xcframework; sourceTree = ""; }; - 8BAF3C56275866860073B30E /* AgoraDav1dExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraDav1dExtension.xcframework; sourceTree = ""; }; - 8BAF3C57275866870073B30E /* Agoraffmpeg.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Agoraffmpeg.xcframework; sourceTree = ""; }; - 8BAF3C58275866870073B30E /* AgoraJNDExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraJNDExtension.xcframework; sourceTree = ""; }; - 8BAF3C59275866870073B30E /* AgoraVideoProcessExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraVideoProcessExtension.xcframework; sourceTree = ""; }; - 8BAF3C5A275866870073B30E /* AgoraVideoSegmentationExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraVideoSegmentationExtension.xcframework; sourceTree = ""; }; - 8BAF3C5B275866870073B30E /* AgoraAIDenoiseExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraAIDenoiseExtension.xcframework; sourceTree = ""; }; - 8BAF3C5C275866880073B30E /* AgoraSuperResolutionExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraSuperResolutionExtension.xcframework; sourceTree = ""; }; - 8BAF3C5D275866880073B30E /* AgoraFDExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraFDExtension.xcframework; sourceTree = ""; }; 8BAF3C952758693A0073B30E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/VideoProcess.strings"; sourceTree = ""; }; 8BAF3C962758693A0073B30E /* VideoProcess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoProcess.swift; sourceTree = ""; }; 8BAF3C982758693A0073B30E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/VideoProcess.storyboard; sourceTree = ""; }; + 8BEA26C6275F4FCF005B7F91 /* Agoraffmpeg.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Agoraffmpeg.xcframework; sourceTree = ""; }; + 8BEA26C7275F4FCF005B7F91 /* AgoraVideoProcessExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraVideoProcessExtension.xcframework; sourceTree = ""; }; + 8BEA26C8275F4FD0005B7F91 /* AgoraFDExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraFDExtension.xcframework; sourceTree = ""; }; + 8BEA26C9275F4FD0005B7F91 /* AgoraVideoSegmentationExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraVideoSegmentationExtension.xcframework; sourceTree = ""; }; + 8BEA26CA275F4FD0005B7F91 /* AgoraFDKAACExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraFDKAACExtension.xcframework; sourceTree = ""; }; + 8BEA26CB275F4FD0005B7F91 /* AgoraSoundTouch.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraSoundTouch.xcframework; sourceTree = ""; }; + 8BEA26CC275F4FD1005B7F91 /* AgoraRtcKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraRtcKit.xcframework; sourceTree = ""; }; + 8BEA26CD275F4FD1005B7F91 /* AgoraCIExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraCIExtension.xcframework; sourceTree = ""; }; + 8BEA26CE275F4FD1005B7F91 /* AgoraJNDExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraJNDExtension.xcframework; sourceTree = ""; }; + 8BEA26CF275F4FD1005B7F91 /* AgoraDav1dExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraDav1dExtension.xcframework; sourceTree = ""; }; + 8BEA26D0275F4FD2005B7F91 /* AgoraAIDenoiseExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraAIDenoiseExtension.xcframework; sourceTree = ""; }; + 8BEA26D1275F4FD2005B7F91 /* AgoraSuperResolutionExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraSuperResolutionExtension.xcframework; sourceTree = ""; }; + 8BEA26D2275F4FD2005B7F91 /* AgoraCore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraCore.xcframework; sourceTree = ""; }; 92EACE913B50B28F1588FE03 /* Pods-Agora-ScreenShare-Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Agora-ScreenShare-Extension.release.xcconfig"; path = "Target Support Files/Pods-Agora-ScreenShare-Extension/Pods-Agora-ScreenShare-Extension.release.xcconfig"; sourceTree = ""; }; 960FD7C836F90E68E6776106 /* Pods_APIExample_Mac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_APIExample_Mac.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A7847F912458062900469187 /* StatisticsInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatisticsInfo.swift; sourceTree = ""; }; @@ -411,23 +349,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8BAF3C65275866880073B30E /* AgoraFDKAACExtension.xcframework in Frameworks */, 0339BE9D25205B7F007D4FDD /* ReplayKit.framework in Frameworks */, - 8BAF3C67275866880073B30E /* AgoraRtcKit.xcframework in Frameworks */, - 8BAF3C69275866880073B30E /* AgoraDav1dExtension.xcframework in Frameworks */, - 8BAF3C77275866880073B30E /* AgoraFDExtension.xcframework in Frameworks */, 0339BEC625207EA7007D4FDD /* Accelerate.framework in Frameworks */, - 8BAF3C61275866880073B30E /* AgoraCIExtension.xcframework in Frameworks */, - 8BAF3C63275866880073B30E /* AgoraSoundTouch.xcframework in Frameworks */, 0339BEC225205D1A007D4FDD /* libios_resampler.a in Frameworks */, CBCDE23FB64E60D6A79F3723 /* Pods_Agora_ScreenShare_Extension.framework in Frameworks */, - 8BAF3C5F275866880073B30E /* AgoraCore.xcframework in Frameworks */, - 8BAF3C75275866880073B30E /* AgoraSuperResolutionExtension.xcframework in Frameworks */, - 8BAF3C71275866880073B30E /* AgoraVideoSegmentationExtension.xcframework in Frameworks */, - 8BAF3C6B275866880073B30E /* Agoraffmpeg.xcframework in Frameworks */, - 8BAF3C6D275866880073B30E /* AgoraJNDExtension.xcframework in Frameworks */, - 8BAF3C6F275866880073B30E /* AgoraVideoProcessExtension.xcframework in Frameworks */, - 8BAF3C73275866880073B30E /* AgoraAIDenoiseExtension.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -435,20 +360,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8BAF3C82275866990073B30E /* AgoraFDKAACExtension.xcframework in Frameworks */, - 8BAF3C78275866980073B30E /* AgoraAIDenoiseExtension.xcframework in Frameworks */, - 8BAF3C86275866990073B30E /* AgoraJNDExtension.xcframework in Frameworks */, - 8BAF3C7A275866980073B30E /* AgoraCIExtension.xcframework in Frameworks */, - 8BAF3C8C275866990073B30E /* AgoraSuperResolutionExtension.xcframework in Frameworks */, - 8BAF3C7E275866990073B30E /* AgoraDav1dExtension.xcframework in Frameworks */, - 8BAF3C8E275866990073B30E /* AgoraVideoProcessExtension.xcframework in Frameworks */, D4046B5D3DE984062E3F6D92 /* Pods_APIExample.framework in Frameworks */, - 8BAF3C88275866990073B30E /* AgoraRtcKit.xcframework in Frameworks */, - 8BAF3C80275866990073B30E /* AgoraFDExtension.xcframework in Frameworks */, - 8BAF3C90275866990073B30E /* AgoraVideoSegmentationExtension.xcframework in Frameworks */, - 8BAF3C8A275866990073B30E /* AgoraSoundTouch.xcframework in Frameworks */, - 8BAF3C7C275866980073B30E /* AgoraCore.xcframework in Frameworks */, - 8BAF3C84275866990073B30E /* Agoraffmpeg.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -815,19 +727,19 @@ 03D13BCE2448758900B599B3 /* APIExample */ = { isa = PBXGroup; children = ( - 8BAF3C5B275866870073B30E /* AgoraAIDenoiseExtension.xcframework */, - 8BAF3C52275866860073B30E /* AgoraCIExtension.xcframework */, - 8BAF3C51275866850073B30E /* AgoraCore.xcframework */, - 8BAF3C56275866860073B30E /* AgoraDav1dExtension.xcframework */, - 8BAF3C5D275866880073B30E /* AgoraFDExtension.xcframework */, - 8BAF3C54275866860073B30E /* AgoraFDKAACExtension.xcframework */, - 8BAF3C57275866870073B30E /* Agoraffmpeg.xcframework */, - 8BAF3C58275866870073B30E /* AgoraJNDExtension.xcframework */, - 8BAF3C55275866860073B30E /* AgoraRtcKit.xcframework */, - 8BAF3C53275866860073B30E /* AgoraSoundTouch.xcframework */, - 8BAF3C5C275866880073B30E /* AgoraSuperResolutionExtension.xcframework */, - 8BAF3C59275866870073B30E /* AgoraVideoProcessExtension.xcframework */, - 8BAF3C5A275866870073B30E /* AgoraVideoSegmentationExtension.xcframework */, + 8BEA26D0275F4FD2005B7F91 /* AgoraAIDenoiseExtension.xcframework */, + 8BEA26CD275F4FD1005B7F91 /* AgoraCIExtension.xcframework */, + 8BEA26D2275F4FD2005B7F91 /* AgoraCore.xcframework */, + 8BEA26CF275F4FD1005B7F91 /* AgoraDav1dExtension.xcframework */, + 8BEA26C8275F4FD0005B7F91 /* AgoraFDExtension.xcframework */, + 8BEA26CA275F4FD0005B7F91 /* AgoraFDKAACExtension.xcframework */, + 8BEA26C6275F4FCF005B7F91 /* Agoraffmpeg.xcframework */, + 8BEA26CE275F4FD1005B7F91 /* AgoraJNDExtension.xcframework */, + 8BEA26CC275F4FD1005B7F91 /* AgoraRtcKit.xcframework */, + 8BEA26CB275F4FD0005B7F91 /* AgoraSoundTouch.xcframework */, + 8BEA26D1275F4FD2005B7F91 /* AgoraSuperResolutionExtension.xcframework */, + 8BEA26C7275F4FCF005B7F91 /* AgoraVideoProcessExtension.xcframework */, + 8BEA26C9275F4FD0005B7F91 /* AgoraVideoSegmentationExtension.xcframework */, 03D13BD52448758900B599B3 /* Main.storyboard */, A7CA48C224553CF600507435 /* Popover.storyboard */, 03D13BD32448758900B599B3 /* ViewController.swift */, @@ -1035,7 +947,6 @@ 03D13BCA2448758900B599B3 /* Resources */, 1B6F6CF9B678035E221EAFDE /* [CP] Embed Pods Frameworks */, 0339BEBA25205B80007D4FDD /* Embed App Extensions */, - 8BAF3C92275866990073B30E /* Embed Frameworks */, ); buildRules = ( ); From 18c446e9b56c803e98fbcbf89617be583e967f7f Mon Sep 17 00:00:00 2001 From: xianing Date: Tue, 7 Dec 2021 16:33:16 +0800 Subject: [PATCH 10/13] adapt latest sdk changes --- iOS/APIExample.xcodeproj/project.pbxproj | 26 ------------------------ 1 file changed, 26 deletions(-) diff --git a/iOS/APIExample.xcodeproj/project.pbxproj b/iOS/APIExample.xcodeproj/project.pbxproj index 231ae8d98..2b5a09425 100644 --- a/iOS/APIExample.xcodeproj/project.pbxproj +++ b/iOS/APIExample.xcodeproj/project.pbxproj @@ -322,19 +322,6 @@ 8BAF3C952758693A0073B30E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/VideoProcess.strings"; sourceTree = ""; }; 8BAF3C962758693A0073B30E /* VideoProcess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoProcess.swift; sourceTree = ""; }; 8BAF3C982758693A0073B30E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/VideoProcess.storyboard; sourceTree = ""; }; - 8BEA26C6275F4FCF005B7F91 /* Agoraffmpeg.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Agoraffmpeg.xcframework; sourceTree = ""; }; - 8BEA26C7275F4FCF005B7F91 /* AgoraVideoProcessExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraVideoProcessExtension.xcframework; sourceTree = ""; }; - 8BEA26C8275F4FD0005B7F91 /* AgoraFDExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraFDExtension.xcframework; sourceTree = ""; }; - 8BEA26C9275F4FD0005B7F91 /* AgoraVideoSegmentationExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraVideoSegmentationExtension.xcframework; sourceTree = ""; }; - 8BEA26CA275F4FD0005B7F91 /* AgoraFDKAACExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraFDKAACExtension.xcframework; sourceTree = ""; }; - 8BEA26CB275F4FD0005B7F91 /* AgoraSoundTouch.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraSoundTouch.xcframework; sourceTree = ""; }; - 8BEA26CC275F4FD1005B7F91 /* AgoraRtcKit.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraRtcKit.xcframework; sourceTree = ""; }; - 8BEA26CD275F4FD1005B7F91 /* AgoraCIExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraCIExtension.xcframework; sourceTree = ""; }; - 8BEA26CE275F4FD1005B7F91 /* AgoraJNDExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraJNDExtension.xcframework; sourceTree = ""; }; - 8BEA26CF275F4FD1005B7F91 /* AgoraDav1dExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraDav1dExtension.xcframework; sourceTree = ""; }; - 8BEA26D0275F4FD2005B7F91 /* AgoraAIDenoiseExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraAIDenoiseExtension.xcframework; sourceTree = ""; }; - 8BEA26D1275F4FD2005B7F91 /* AgoraSuperResolutionExtension.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraSuperResolutionExtension.xcframework; sourceTree = ""; }; - 8BEA26D2275F4FD2005B7F91 /* AgoraCore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = AgoraCore.xcframework; sourceTree = ""; }; 92EACE913B50B28F1588FE03 /* Pods-Agora-ScreenShare-Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Agora-ScreenShare-Extension.release.xcconfig"; path = "Target Support Files/Pods-Agora-ScreenShare-Extension/Pods-Agora-ScreenShare-Extension.release.xcconfig"; sourceTree = ""; }; 960FD7C836F90E68E6776106 /* Pods_APIExample_Mac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_APIExample_Mac.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A7847F912458062900469187 /* StatisticsInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatisticsInfo.swift; sourceTree = ""; }; @@ -727,19 +714,6 @@ 03D13BCE2448758900B599B3 /* APIExample */ = { isa = PBXGroup; children = ( - 8BEA26D0275F4FD2005B7F91 /* AgoraAIDenoiseExtension.xcframework */, - 8BEA26CD275F4FD1005B7F91 /* AgoraCIExtension.xcframework */, - 8BEA26D2275F4FD2005B7F91 /* AgoraCore.xcframework */, - 8BEA26CF275F4FD1005B7F91 /* AgoraDav1dExtension.xcframework */, - 8BEA26C8275F4FD0005B7F91 /* AgoraFDExtension.xcframework */, - 8BEA26CA275F4FD0005B7F91 /* AgoraFDKAACExtension.xcframework */, - 8BEA26C6275F4FCF005B7F91 /* Agoraffmpeg.xcframework */, - 8BEA26CE275F4FD1005B7F91 /* AgoraJNDExtension.xcframework */, - 8BEA26CC275F4FD1005B7F91 /* AgoraRtcKit.xcframework */, - 8BEA26CB275F4FD0005B7F91 /* AgoraSoundTouch.xcframework */, - 8BEA26D1275F4FD2005B7F91 /* AgoraSuperResolutionExtension.xcframework */, - 8BEA26C7275F4FCF005B7F91 /* AgoraVideoProcessExtension.xcframework */, - 8BEA26C9275F4FD0005B7F91 /* AgoraVideoSegmentationExtension.xcframework */, 03D13BD52448758900B599B3 /* Main.storyboard */, A7CA48C224553CF600507435 /* Popover.storyboard */, 03D13BD32448758900B599B3 /* ViewController.swift */, From ab1eb06e4213b1cc7823dc74ed532eec42a4973a Mon Sep 17 00:00:00 2001 From: xianing Date: Thu, 9 Dec 2021 21:13:05 +0800 Subject: [PATCH 11/13] update podfile --- .../CustomPcmAudioSource/CustomPcmAudioSource.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iOS/APIExample/Examples/Advanced/CustomPcmAudioSource/CustomPcmAudioSource.swift b/iOS/APIExample/Examples/Advanced/CustomPcmAudioSource/CustomPcmAudioSource.swift index 1f275c922..4a133b31c 100644 --- a/iOS/APIExample/Examples/Advanced/CustomPcmAudioSource/CustomPcmAudioSource.swift +++ b/iOS/APIExample/Examples/Advanced/CustomPcmAudioSource/CustomPcmAudioSource.swift @@ -151,9 +151,9 @@ extension CustomPcmAudioSourceMain: AgoraPcmSourcePushDelegate { func onAudioFrame(data: UnsafeMutablePointer, samples: UInt) { let frame = AgoraAudioFrame() frame.buffer = UnsafeMutableRawPointer(data) - frame.samplesPerSec = 48000 - frame.channels = 2 - frame.bytesPerSample = 32 * 8 + frame.samplesPerSec = Int(sampleRate) + frame.channels = Int(channel) + frame.bytesPerSample = 2 frame.samplesPerChannel = self.samples / 2 let ret = agoraKit.pushExternalAudioFrameRawData(pushPos, frame: frame) print("push result: \(ret)") From a4f4ad4fa9afd0529f518c9ae7a8e93ed81d5bfa Mon Sep 17 00:00:00 2001 From: xianing Date: Fri, 10 Dec 2021 22:46:38 +0800 Subject: [PATCH 12/13] set default audio route to speaker phone --- .../java/io/agora/api/example/examples/advanced/ARCore.java | 2 +- .../agora/api/example/examples/advanced/ChannelEncryption.java | 2 +- .../api/example/examples/advanced/CustomRemoteVideoRender.java | 2 +- .../java/io/agora/api/example/examples/advanced/GeoFencing.java | 2 +- .../agora/api/example/examples/advanced/HostAcrossChannel.java | 2 +- .../io/agora/api/example/examples/advanced/InCallReport.java | 2 +- .../api/example/examples/advanced/JoinMultipleChannel.java | 2 +- .../io/agora/api/example/examples/advanced/LiveStreaming.java | 2 +- .../io/agora/api/example/examples/advanced/MediaPlayerKit.java | 2 +- .../io/agora/api/example/examples/advanced/ProcessRawData.java | 2 +- .../agora/api/example/examples/advanced/PushExternalVideo.java | 2 +- .../io/agora/api/example/examples/advanced/RTMPStreaming.java | 2 +- .../io/agora/api/example/examples/advanced/SendDataStream.java | 2 +- .../io/agora/api/example/examples/advanced/SetVideoProfile.java | 2 +- .../io/agora/api/example/examples/advanced/StreamEncrypt.java | 2 +- .../io/agora/api/example/examples/advanced/SuperResolution.java | 2 +- .../api/example/examples/advanced/SwitchExternalVideo.java | 2 +- .../io/agora/api/example/examples/advanced/VideoMetadata.java | 2 +- .../agora/api/example/examples/advanced/VideoQuickSwitch.java | 2 +- .../io/agora/api/example/examples/basic/JoinChannelVideo.java | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ARCore.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ARCore.java index f9e7f9db4..bbb9ca94d 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ARCore.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ARCore.java @@ -294,7 +294,7 @@ private void joinChannel(String channelId) } // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ChannelEncryption.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ChannelEncryption.java index 65afde86a..7c29b4869 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ChannelEncryption.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ChannelEncryption.java @@ -207,7 +207,7 @@ private void joinChannel(String channelId) // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/CustomRemoteVideoRender.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/CustomRemoteVideoRender.java index 6a15c308a..276dfa8fc 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/CustomRemoteVideoRender.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/CustomRemoteVideoRender.java @@ -174,7 +174,7 @@ private void joinChannel(String channelId) { // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); /**Set up to play remote sound with receiver*/ - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); engine.setEnableSpeakerphone(false); /** Sets the channel profile of the Agora RtcEngine. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/GeoFencing.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/GeoFencing.java index fe78b663c..dca4be4f7 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/GeoFencing.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/GeoFencing.java @@ -207,7 +207,7 @@ private void joinChannel(String channelId) { // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/HostAcrossChannel.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/HostAcrossChannel.java index ad833be99..e173cdcbc 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/HostAcrossChannel.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/HostAcrossChannel.java @@ -225,7 +225,7 @@ private void joinChannel(String channelId) // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/InCallReport.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/InCallReport.java index 7a2b1e641..ac6aa24d0 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/InCallReport.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/InCallReport.java @@ -203,7 +203,7 @@ private void joinChannel(String channelId) // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/JoinMultipleChannel.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/JoinMultipleChannel.java index 3caf3f143..67a2aba4f 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/JoinMultipleChannel.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/JoinMultipleChannel.java @@ -200,7 +200,7 @@ private void setupVideo() engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); engine.startPreview(); // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/LiveStreaming.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/LiveStreaming.java index 2600c1c66..e35843b90 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/LiveStreaming.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/LiveStreaming.java @@ -232,7 +232,7 @@ private void joinChannel(String channelId) { // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/MediaPlayerKit.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/MediaPlayerKit.java index 2fb4238a4..b3ac96898 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/MediaPlayerKit.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/MediaPlayerKit.java @@ -310,7 +310,7 @@ private void joinChannel(String channelId) { return; } - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ProcessRawData.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ProcessRawData.java index d35a128be..dfdaa5cb1 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ProcessRawData.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ProcessRawData.java @@ -218,7 +218,7 @@ private void joinChannel(String channelId) { VideoEncoderConfiguration.ORIENTATION_MODE.valueOf(((MainApplication)getActivity().getApplication()).getGlobalSettings().getVideoEncodingOrientation()) )); /**Set up to play remote sound with receiver*/ - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); engine.setEnableSpeakerphone(false); /** diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/PushExternalVideo.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/PushExternalVideo.java index 88e141ad4..f7597d12a 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/PushExternalVideo.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/PushExternalVideo.java @@ -202,7 +202,7 @@ private void joinChannel(String channelId) { fl_local.addView(textureView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); /**Set up to play remote sound with receiver*/ - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); engine.setEnableSpeakerphone(false); /** Sets the channel profile of the Agora RtcEngine. 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 6b3bc030a..1de8e3993 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 @@ -220,7 +220,7 @@ private void joinChannel(String channelId) { VideoEncoderConfiguration.ORIENTATION_MODE.valueOf(((MainApplication)getActivity().getApplication()).getGlobalSettings().getVideoEncodingOrientation()) )); /**Set up to play remote sound with receiver*/ - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); engine.setEnableSpeakerphone(false); /**Please configure accessToken in the string_config file. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SendDataStream.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SendDataStream.java index 392937edf..a686be99c 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SendDataStream.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SendDataStream.java @@ -222,7 +222,7 @@ private void joinChannel(String channelId) VideoEncoderConfiguration.ORIENTATION_MODE.valueOf(((MainApplication)getActivity().getApplication()).getGlobalSettings().getVideoEncodingOrientation()) )); /**Set up to play remote sound with receiver*/ - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); engine.setEnableSpeakerphone(false); /**Please configure accessToken in the string_config file. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SetVideoProfile.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SetVideoProfile.java index 24a73ed81..664ccacf5 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SetVideoProfile.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SetVideoProfile.java @@ -250,7 +250,7 @@ private void joinChannel(String channelId) // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/StreamEncrypt.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/StreamEncrypt.java index 1d38e8b64..02775f025 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/StreamEncrypt.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/StreamEncrypt.java @@ -190,7 +190,7 @@ private void joinChannel(String channelId) // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); /**Set up to play remote sound with receiver*/ - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); engine.setEnableSpeakerphone(false); /** Sets the channel profile of the Agora RtcEngine. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SuperResolution.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SuperResolution.java index 36a9b55ff..df3d2c78e 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SuperResolution.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SuperResolution.java @@ -196,7 +196,7 @@ private void joinChannel(String channelId) // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SwitchExternalVideo.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SwitchExternalVideo.java index af686e580..a74abed71 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SwitchExternalVideo.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/SwitchExternalVideo.java @@ -292,7 +292,7 @@ private void joinChannel(String channelId) { /**Enable video module*/ ENGINE.enableVideo(); /**Set up to play remote sound with receiver*/ - ENGINE.setDefaultAudioRoutetoSpeakerphone(false); + ENGINE.setDefaultAudioRoutetoSpeakerphone(true); ENGINE.setEnableSpeakerphone(false); /**Please configure accessToken in the string_config file. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoMetadata.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoMetadata.java index 7104358fb..11ea6eb93 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoMetadata.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoMetadata.java @@ -225,7 +225,7 @@ private void joinChannel(String channelId) VideoEncoderConfiguration.ORIENTATION_MODE.valueOf(((MainApplication)getActivity().getApplication()).getGlobalSettings().getVideoEncodingOrientation()) )); /**Set up to play remote sound with receiver*/ - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); engine.setEnableSpeakerphone(false); /**register metadata observer diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoQuickSwitch.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoQuickSwitch.java index 1de8ab193..2559c15bf 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoQuickSwitch.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/VideoQuickSwitch.java @@ -261,7 +261,7 @@ private final void joinChannel(String channelId) VideoEncoderConfiguration.ORIENTATION_MODE.valueOf(((MainApplication)getActivity().getApplication()).getGlobalSettings().getVideoEncodingOrientation()) )); /**Set up to play remote sound with receiver*/ - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); engine.setEnableSpeakerphone(false); /**Please configure accessToken in the string_config file. diff --git a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/basic/JoinChannelVideo.java b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/basic/JoinChannelVideo.java index d65198fb3..bb1cac0f1 100644 --- a/Android/APIExample/app/src/main/java/io/agora/api/example/examples/basic/JoinChannelVideo.java +++ b/Android/APIExample/app/src/main/java/io/agora/api/example/examples/basic/JoinChannelVideo.java @@ -217,7 +217,7 @@ private void joinChannel(String channelId) // Setup local video to render your local camera preview engine.setupLocalVideo(new VideoCanvas(surfaceView, RENDER_MODE_HIDDEN, 0)); // Set audio route to microPhone - engine.setDefaultAudioRoutetoSpeakerphone(false); + engine.setDefaultAudioRoutetoSpeakerphone(true); /** Sets the channel profile of the Agora RtcEngine. CHANNEL_PROFILE_COMMUNICATION(0): (Default) The Communication profile. From c167883e423118d50ee603ef85a57de253e6a37f Mon Sep 17 00:00:00 2001 From: xianing Date: Sun, 19 Dec 2021 10:12:48 +0800 Subject: [PATCH 13/13] fix mac localization issues --- macOS/APIExample.xcodeproj/project.pbxproj | 32 ++++++++++++------- .../{ => zh-Hans.lproj}/Localizable.strings | 0 macOS/Podfile | 2 +- 3 files changed, 21 insertions(+), 13 deletions(-) rename macOS/APIExample/{ => zh-Hans.lproj}/Localizable.strings (100%) diff --git a/macOS/APIExample.xcodeproj/project.pbxproj b/macOS/APIExample.xcodeproj/project.pbxproj index c5a5b45c5..691d22a03 100644 --- a/macOS/APIExample.xcodeproj/project.pbxproj +++ b/macOS/APIExample.xcodeproj/project.pbxproj @@ -43,7 +43,6 @@ 033A9FF5252EB5F400BC26E1 /* JoinMultiChannel.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 033A9FF7252EB5F400BC26E1 /* JoinMultiChannel.storyboard */; }; 033A9FFA252EB5FD00BC26E1 /* ScreenShare.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 033A9FFC252EB5FD00BC26E1 /* ScreenShare.storyboard */; }; 033A9FFF252EB60800BC26E1 /* StreamEncryption.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 033AA001252EB60800BC26E1 /* StreamEncryption.storyboard */; }; - 033AA005252EBBEC00BC26E1 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 033AA004252EBBEC00BC26E1 /* Localizable.strings */; }; 034C626425257EA600296ECF /* GlobalSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034C626325257EA600296ECF /* GlobalSettings.swift */; }; 034C62672525857200296ECF /* JoinChannelAudio.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034C62662525857200296ECF /* JoinChannelAudio.swift */; }; 034C626C25259FC200296ECF /* JoinChannelVideo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 034C626B25259FC200296ECF /* JoinChannelVideo.swift */; }; @@ -88,6 +87,7 @@ 57AF397B259B31AA00601E02 /* RawAudioData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57AF397A259B31AA00601E02 /* RawAudioData.swift */; }; 57AF3981259B329B00601E02 /* RawAudioData.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 57AF3980259B329B00601E02 /* RawAudioData.storyboard */; }; 596A9F79AF0CD8DC1CA93253 /* Pods_APIExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F65EF2B97B89DE4581B426B /* Pods_APIExample.framework */; }; + 8B6F4EAD276ECC370097E67E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8B6F4EAF276ECC370097E67E /* Localizable.strings */; }; 8B733B8C267B1C0B00CC3DE3 /* bg.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B733B8B267B1C0B00CC3DE3 /* bg.jpg */; }; EBDD0209B272C276B21B6270 /* Pods_APIExample_APIExampleUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC2BAB0AC82140B7CEEA31DA /* Pods_APIExample_APIExampleUITests.framework */; }; /* End PBXBuildFile section */ @@ -173,7 +173,6 @@ 033A9FFB252EB5FD00BC26E1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/ScreenShare.storyboard; sourceTree = ""; }; 033AA000252EB60800BC26E1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/StreamEncryption.storyboard; sourceTree = ""; }; 033AA003252EB60B00BC26E1 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/StreamEncryption.strings"; sourceTree = ""; }; - 033AA004252EBBEC00BC26E1 /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; 034C626325257EA600296ECF /* GlobalSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalSettings.swift; sourceTree = ""; }; 034C62662525857200296ECF /* JoinChannelAudio.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JoinChannelAudio.swift; sourceTree = ""; }; 034C626B25259FC200296ECF /* JoinChannelVideo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JoinChannelVideo.swift; sourceTree = ""; }; @@ -230,6 +229,7 @@ 57AF3980259B329B00601E02 /* RawAudioData.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = RawAudioData.storyboard; sourceTree = ""; }; 6F65EF2B97B89DE4581B426B /* Pods_APIExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_APIExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84C863718A380DFD36ABF19F /* Pods-APIExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIExample.debug.xcconfig"; path = "Target Support Files/Pods-APIExample/Pods-APIExample.debug.xcconfig"; sourceTree = ""; }; + 8B6F4EAE276ECC370097E67E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 8B733B8B267B1C0B00CC3DE3 /* bg.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = bg.jpg; sourceTree = ""; }; B53F41CB5AC550EA43C47363 /* Pods-APIExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-APIExampleTests/Pods-APIExampleTests.debug.xcconfig"; sourceTree = ""; }; B91A67063F1DBE9F621B114C /* Pods-APIExample-APIExampleUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIExample-APIExampleUITests.release.xcconfig"; path = "Target Support Files/Pods-APIExample-APIExampleUITests/Pods-APIExample-APIExampleUITests.release.xcconfig"; sourceTree = ""; }; @@ -520,7 +520,7 @@ 03896D2E24F8A00F008593CD /* APIExample */ = { isa = PBXGroup; children = ( - 033AA004252EBBEC00BC26E1 /* Localizable.strings */, + 8B6F4EAF276ECC370097E67E /* Localizable.strings */, 034C629D25297ABB00296ECF /* Resources */, 03267E262500C779004A91A6 /* APIExample-Bridging-Header.h */, 0333E63824FA335C0063C5B0 /* Examples */, @@ -777,7 +777,7 @@ 033A9FFA252EB5FD00BC26E1 /* ScreenShare.storyboard in Resources */, 57645A03259B1C22007B1E30 /* CreateDataStream.strings in Resources */, 5770E2D5258C9E6F00812A80 /* Picker.xib in Resources */, - 033AA005252EBBEC00BC26E1 /* Localizable.strings in Resources */, + 8B6F4EAD276ECC370097E67E /* Localizable.strings in Resources */, 57887A67258856B7006E962A /* Settings.storyboard in Resources */, 033A9FFF252EB60800BC26E1 /* StreamEncryption.storyboard in Resources */, 0301D31D2507C0F300DF3BEA /* MetalVideoView.xib in Resources */, @@ -1182,6 +1182,14 @@ name = Settings.storyboard; sourceTree = ""; }; + 8B6F4EAF276ECC370097E67E /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 8B6F4EAE276ECC370097E67E /* zh-Hans */, + ); + name = Localizable.strings; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -1306,10 +1314,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = APIExample/APIExample.entitlements; - CODE_SIGN_IDENTITY = "Developer ID Application"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = GM72UGLGZW; + DEVELOPMENT_TEAM = YS397FG5PA; ENABLE_HARDENED_RUNTIME = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1322,7 +1330,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = io.agora.api.example.APIExample; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = apiexamplemac; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "APIExample/APIExample-Bridging-Header.h"; SWIFT_VERSION = 5.0; }; @@ -1334,10 +1342,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = APIExample/APIExample.entitlements; - CODE_SIGN_IDENTITY = "Developer ID Application"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = GM72UGLGZW; + DEVELOPMENT_TEAM = YS397FG5PA; ENABLE_HARDENED_RUNTIME = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1350,7 +1358,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = io.agora.api.example.APIExample; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = apiexamplemac; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "APIExample/APIExample-Bridging-Header.h"; SWIFT_VERSION = 5.0; }; diff --git a/macOS/APIExample/Localizable.strings b/macOS/APIExample/zh-Hans.lproj/Localizable.strings similarity index 100% rename from macOS/APIExample/Localizable.strings rename to macOS/APIExample/zh-Hans.lproj/Localizable.strings diff --git a/macOS/Podfile b/macOS/Podfile index 4b8def9bb..c75c54009 100644 --- a/macOS/Podfile +++ b/macOS/Podfile @@ -7,7 +7,7 @@ target 'APIExample' do # Pods for APIExample pod 'AGEVideoLayout', '~> 1.0.2' - pod 'AgoraRtcEngine_macOS', '3.5.2' + pod 'AgoraRtcEngine_macOS', '3.6.0.1' target 'APIExampleTests' do inherit! :search_paths