Agora.io 音频正常但视频不传输

Posted

技术标签:

【中文标题】Agora.io 音频正常但视频不传输【英文标题】:Agora.io audio working but video not transmitting 【发布时间】:2020-10-20 08:50:32 【问题描述】:

我是 Agora.io 的新手,我正在创建一个用于 1 对 1 视频通话的 android 应用。我的应用程序一切正常 - 我可以加入/离开频道,甚至可以通过我的相机查看我自己的本地图像。但是,在通话中,只传输音频,不传输视频。

当我调试应用程序时,我可以看到事件“onFirstRemoteVideoFrame”没有被触发。我尝试将其更改为“onFirstRemoteVideoDecoded”(我在许多教程中都看到过,但 android studio 说该方法已被贬值)但它仍然无法正常工作。

另外,请注意,当我在我的 proguard-rules.pro 文件中添加“-keep class io.agora.**;”行时,它说找不到类。所以我使用的是'-keep class io.agora.*;'。

以下是我的活动的 java 代码。我正在使用agora 3.1.3。

package com.guideu.helloagora;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import io.agora.rtc.IRtcEngineEventHandler;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.video.VideoCanvas;

import io.agora.rtc.video.VideoEncoderConfiguration;

public class MainActivity extends AppCompatActivity 

    private static final String TAG=MainActivity.class.getSimpleName();

    private static final int PERMISSION_REQ_ID=22;

    private static final String[] REQUESTED_PERMISSIONS=
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.CAMERA,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    ;

    private RtcEngine mRtcEngine; // Agora engine reference

    private FrameLayout mLocalContainer;
    private RelativeLayout mRemoteContainer;
    private SurfaceView mLocalView;
    private SurfaceView mRemoteView;

    private ImageView mCallBtn;
    private ImageView mMuteBtn;
    private ImageView mSwitchCameraBtn;

    private boolean mCallEnd;
    private boolean mMuted;

    //Agora engine event handler
    private final IRtcEngineEventHandler mRTCHandler=new IRtcEngineEventHandler() 
        @Override
        public void onJoinChannelSuccess(String channel, final int uid, int elapsed) 
            super.onJoinChannelSuccess(channel, uid, elapsed);
            runOnUiThread(new Runnable() 
                @Override
                public void run() 
                    Log.i("agora","Join channel success, uid: " + (uid & 0xFFFFFFFFL));
                
            );
        

        @Override
        public void onUserOffline(final int uid, int reason) 
            super.onUserOffline(uid, reason);
            runOnUiThread(new Runnable() 
                @Override
                public void run() 
                    Log.i("agora","User offline, uid: " + (uid & 0xFFFFFFFFL));
                    removeRemoteView();
                
            );
        

        @Override
        public void onFirstRemoteVideoFrame(final int uid, int width, int height, int elapsed) 
            super.onFirstRemoteVideoFrame(uid, width, height, elapsed);
            runOnUiThread(new Runnable() 
                @Override
                public void run() 
                    Log.i("agora","First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
                    setupRemoteVideo(uid);
                
            );
        
    ;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initUI();

        if(checkSelfPermission(REQUESTED_PERMISSIONS[0],PERMISSION_REQ_ID) &&
                checkSelfPermission(REQUESTED_PERMISSIONS[1],PERMISSION_REQ_ID) &&
        checkSelfPermission(REQUESTED_PERMISSIONS[2],PERMISSION_REQ_ID))
            //init engine
            initEngineAndJoinChannel();
        
    

    @Override
    protected void onDestroy()
        super.onDestroy();
        if(!mCallEnd)
            leaveChannel();
        
        RtcEngine.destroy();
    

    private void initUI()
        mLocalContainer=findViewById(R.id.local_video_view_container);
        mRemoteContainer=findViewById(R.id.remote_video_view_container);

        mCallBtn=findViewById(R.id.btn_call);
        mMuteBtn=findViewById(R.id.btn_mute);
        mSwitchCameraBtn=findViewById(R.id.btn_switch_camera);
    

    private void initEngineAndJoinChannel()
        //initialize engine
        initializeEngine();
        //setup video config
        setupVideoConfig();
        //setup local video
        setupLocalVideo();
        //join channel
        joinChannel();
    

    private void initializeEngine()
        try 
            mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.agora_app_id), mRTCHandler);
        
        catch (Exception e)
            Log.e(TAG,Log.getStackTraceString(e));
            throw new RuntimeException("Need to check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
        
    

    private void setupVideoConfig()
        mRtcEngine.enableVideo();

        mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
                VideoEncoderConfiguration.VD_640x360,
                VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
                VideoEncoderConfiguration.STANDARD_BITRATE,
                VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT
        ));
    

    private void setupLocalVideo()
        mRtcEngine.enableVideo();

        mLocalView=RtcEngine.CreateRendererView(getBaseContext());
        mLocalView.setZOrderMediaOverlay(true);
        mLocalContainer.addView(mLocalView);

        VideoCanvas localVideoCanvas=new VideoCanvas(mLocalView,VideoCanvas.RENDER_MODE_HIDDEN,0);
        mRtcEngine.setupLocalVideo(localVideoCanvas);
    

    private void setupRemoteVideo(int uid)
        /*int count=mRemoteContainer.getChildCount();
        View view=null;
        for(int i=0;i<count;i++)
            View v=mRemoteContainer.getChildAt(i);
            if(v.getTag() instanceof  Integer && ((int) v.getTag())==uid)
                view=v;
            
        

        if(view!=null)
            return;
        */

        mRemoteView=RtcEngine.CreateRendererView(getBaseContext());
        mRemoteContainer.addView(mRemoteView);
        mRtcEngine.setupRemoteVideo(new VideoCanvas(mRemoteView,VideoCanvas.RENDER_MODE_HIDDEN,uid));
        mRemoteView.setTag(uid);
    

    private void removeRemoteView()
        if(mRemoteView!=null)
            mRemoteContainer.removeView(mRemoteView);
        

        mRemoteView=null;
    

    private void joinChannel()
        String token=getString(R.string.agora_access_token);
        if(TextUtils.isEmpty(token))
            token=null;
        

        mRtcEngine.joinChannel(token,"HelloAgora","",0);
    

    private void leaveChannel()
        mRtcEngine.leaveChannel();
    

    public void onLocalAudioMuteClicked(View view)
        mMuted=!mMuted;
        mRtcEngine.muteLocalAudiostream(mMuted);
        int res=mMuted?R.drawable.btn_mutecall:R.drawable.btn_unmute;
        mMuteBtn.setImageResource(res);
    

    public void onSwitchCameraClicked(View view)
        mRtcEngine.switchCamera();
    

    public void onCallClicked(View view)
        if(mCallEnd)
            startCall();
            mCallEnd=false;
            mCallBtn.setImageResource(R.drawable.btn_endcall);
        
        else
            endCall();
            mCallEnd=true;
            mCallBtn.setImageResource(R.drawable.btn_startcall);
        

        showButtons(!mCallEnd);
    

    private void startCall()
        setupLocalVideo();
        joinChannel();
    

    private void endCall()
        removeLocalVideo();
        removeRemoteView();
        leaveChannel();
    

    private void removeLocalVideo()
        if(mLocalView!=null)
            mLocalContainer.removeView(mLocalView);
        
        mLocalView=null;
    

    private void showButtons(boolean show)
        int visibility=show?View.VISIBLE:View.GONE;
        mMuteBtn.setVisibility(visibility);
        mSwitchCameraBtn.setVisibility(visibility);
    

    private boolean checkSelfPermission(String permission, int requestCode)
        if(ContextCompat.checkSelfPermission(this,permission)!= PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(this,REQUESTED_PERMISSIONS,requestCode);
            Toast.makeText(this,"No Permission",Toast.LENGTH_LONG);
            return false;
        

        return true;
    

'''

【问题讨论】:

【参考方案1】:

您可以尝试“onRemoteVideoStateChanged”回调而不是“onFirstRemoteVideoFrame”。

这里是sn-p的代码:

@Override
    public void onRemoteVideoStateChanged(final int uid, int state, int reason, int elapsed) 
        super.onRemoteVideoStateChanged(uid, state, reason, elapsed);
        if (state == Constants.REMOTE_VIDEO_STATE_STARTING) 
            runOnUiThread(new Runnable() 
                @Override
                public void run() 
                    setupRemoteVideo(uid);
                
            );
        
    

【讨论】:

以上是关于Agora.io 音频正常但视频不传输的主要内容,如果未能解决你的问题,请参考以下文章

使用 Agora Flutter 传入的视频/音频呼叫通知

Agora.io 从 LiveStream 录制音频

我正在使用适用于 Agora.io 的 Android SDK 并尝试实现实时音频广播。出现错误

如何在 URL 中嵌入 App ID 和 Channel ID (Agora.io)

流式传输音频时看不到 MPMoviePlayerControls

搜索文件时 MPMoviePlayer 播放音频但不播放视频