当前位置:   article > 正文

你了解视频 API 吗?_视频开放api

视频开放api

本文介绍什么是视频 API?视频API如何保证音视频的流畅传输?

什么是视频 API?

Video API是专门提供音视频传输服务的接口,主要分为静态视频API和直播视频API两种。

静态视频 API

静态视频 API 是提供视频文件播放服务的 API。服务商提供视频文件云存储和CDN分发服务,通过HTTP、RTMP等协议接口提供视频服务。

例如,YouTube 和 Instagram 使用静态视频 API。

直播视频 API

例如,Live.me、Yalla 和 Uplive 使用 Live Video API。

静态视频 API 易于理解,通过流协议从云端拉取视频文件。

直播视频 API 更复杂。如何保证视频能够快速、流畅、清晰地传输到另一端?

在本文中,我们将详细介绍视频直播 API 背后的逻辑。

视频 API 能做什么?

随着网络带宽和设备性能的不断提高,直播视频API应用越来越广泛。它使许多场景成为可能,例如:

  • 居住
  • 在线教育
  • 视频会议
  • 远程医疗
  • 视频通话
  • 多人游戏

视频 API 之后会发生什么?

对于视频直播API,需要保证视频数据能够在500ms内完成端到端的传输,同时保证视频画面的清晰度和通话的流畅性。

因此,视频直播API需要保证音视频数据能够以快速、大容量、稳定的方式实现端到端的数据传输。需要一个复杂的系统来确保实时视频 API 的可用性。


如图所示,视频直播API主要对6个模块的功能进行了分层:

1.音视频采集

音视频采集是通过摄像头、麦克风、屏幕、视频文件、录音文件等渠道采集的音视频数据的来源。

它涉及使用颜色空间,例如RGB和YUV,并提取音频特征,例如采样率、通道数、比特率、音频帧等。

2.音视频预处理

音视频预处理主要针对业务场景,对采集到的数据进行一次次处理,优化客户体验。

例如:

  • 美颜、滤镜、特效等视频数据处理
  • 音频数据处理包括语音变化、混响、回声消除、噪声抑制、音量增益等。

3.音视频编码

音视频编码保证了音视频数据能够在网络上快速安全地传输。

常用的编码格式有视频编码格式:H264、H265音频编码格式:OPUS、AAC。

4.音视频传输

音视频传输是视频API中最复杂的模块。为了保证音视频数据在复杂的网络环境下能够快速、稳定、高质量地传输到对端,可以使用RTP、HTTP-FLV、HLS、RTMP等流协议。

数据冗余、丢失、乱序、流控、自适应帧率、分辨率、抖动缓冲等各种异常,必须使用多种算法来解决。

所以视频API是否值得选择,需要关注厂商是否具备突出的音视频传输优势。

5.音视频解码

音视频解码是指将音视频数据传输到接收端后,接收端需要根据接收到的数据编码格式对数据进行解码。

有两种视频解码方法,硬件解码和软件解码。软件解码一般使用开源库FFMpeg。音频解码只支持软件解码;根据音频编码格式使用FDK_AAC或OPUS解码。

6.音视频渲染

音频和视频渲染是视频 API 处理过程的最后一步。这一步看起来很简单。您只需要调用系统接口将数据渲染到屏幕上。

然而,必须处理很多逻辑来将视频图像与音频对齐。尽管如此,现在还是有一种标准的处理方法来确保音频和视频的同步。

如何使用 ZEGOCLOUD 视频 API

构建一套完整的实时音视频系统是一项复杂的工作。尽管如此,许多视频 API 帮助我们解决了底层的复杂操作。我们只需要关注上层的业务逻辑。

下面将介绍如何使用ZEGOCLOUD Video API来实现视频通话功能。

实施过程

1.下图是用户A播放用户B发布的流的基本流程:


以下部分更详细地解释了此过程的每个步骤。

2. 可选:创建 UI

在创建ZegoExpressEngine实例之前,我们建议您添加以下 UI 元素来实现基本的实时音视频功能:

  • 本地预览视图
  • 远程视频视图
  • 结束按钮

3.创建一个ZegoExpressEngine实例

要创建该类的单例实例,请使用项目的AppIDZegoExpressEngine调用该createEngine方法。

/** Define a ZegoExpressEngine object */
ZegoExpressEngine engine;

ZegoEngineProfile profile = new ZegoEngineProfile();
/** AppID format: 123456789L */
profile.appID = appID;
/** General scenario */
profile.scenario = ZegoScenario.GENERAL;
/** Set application object of App */
profile.application = getApplication();
/** Create a ZegoExpressEngine instance */
engine = ZegoExpressEngine.createEngine(profile, null);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4. 登录房间

要登录房间,请调用该loginRoom方法。

ZegoUser user = new ZegoUser("user1");


ZegoRoomConfig roomConfig = new ZegoRoomConfig();
/** Token is generated by the user's own server. For an easier and convenient debugging, you can get a temporary token from the ZEGOCLOUD Admin Console */
roomConfig.token = "xxxx";
/** onRoomUserUpdate callback can be received only by passing in a ZegoRoomConfig whose "isUserStatusNotify" parameter value is "true".*/
roomConfig.isUserStatusNotify = true;

/** log in to a room */
engine.loginRoom("room1", user, roomConfig, (int error, JSONObject extendedData)->{
    // (Optional callback) The result of logging in to the room. If you only pay attention to the login result, you can use this callback.
});  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

然后,为了监听和处理登录房间后可能发生的各种事件,可以根据需要实现事件处理器的相应事件回调方法。

engine.setEventHandler(new IZegoEventHandler() {

    /** Common event callbacks related to room users and streams. */

    /** Callback for updates on the current user's room connection status. */
    @Override
    public void onRoomStateUpdate(String roomID, ZegoRoomState state, int errorCode, JSONObject extendedData) {
        /** Implement the callback handling logic as needed. */
    }

    /** Callback for updates on the status of other users in the room. */
    @Override
    public void onRoomUserUpdate(String roomID, ZegoUpdateType updateType, ArrayList<ZegoUser> userList) {
        /** Implement the callback handling logic as needed. */
    }

    /** Callback for updates on the status of the streams in the room. */
    @Override
    public void onRoomStreamUpdate(String roomID, ZegoUpdateType updateType, ArrayList<ZegoStream> streamList, JSONObject extendedData){
        /** Implement the callback handling logic as needed. */
     }

});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

5.启动本地视频预览

要启动本地视频预览,请startPreview使用传递给canvas参数的用于渲染本地视频的视图调用该方法。

您可以使用SurfaceView、TextureView或SurfaceTexture来渲染视频。

 *  Set up a view for the local video preview and start the preview with SDK's default view mode (AspectFill).
 *  The following play_view is a SurfaceView, TextureView, or SurfaceTexture object on the UI.
 */
engine.startPreview(new ZegoCanvas(preview_view));
  • 1
  • 2
  • 3
  • 4

6.发布流

要开始向远程用户发布本地音频或视频流,请调用startPublishingStream方法,并将相应的流ID传递给streamID参数。

/** Start publishing a stream */
engine.startPublishingStream("stream1");
  • 1
  • 2

然后,为了监听和处理流发布开始后可能发生的各种事件,您可以根据需要实现事件处理器的相应事件回调方法。

engine.setEventHandler(new IZegoEventHandler() {
    /** Common event callbacks related to stream publishing. */

    /** Callback for updates on stream publishing status.   */
    @Override
    public void onPublisherStateUpdate(String streamID, ZegoPublisherState state, int errorCode, JSONObject extendedData){
        /** Implement the callback handling logic as needed. */
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

7.播放流

要开始播放远程音频或视频流,请调用startPlayingStream方法,将相应的流ID传递给streamID参数,并将用于渲染视频的视图传递给canvas参数。

您可以使用SurfaceView、TextureView或SurfaceTexture来渲染视频。

/**
 *  Start playing a remote stream with the SDK's default view mode (AspectFill).
 *  The play_view below is a SurfaceView/TextureView/SurfaceTexture object on UI.
 */
engine.startPlayingStream("stream1", new ZegoCanvas(play_view));
  • 1
  • 2
  • 3
  • 4
  • 5

8.停止发布和播放流

要停止向远程用户发布本地音频或视频流,请调用该stopPublishingStream方法。

/** Stop publishing a stream */
engine.stopPublishingStream();
  • 1
  • 2

如果本地视频预览启动,stopPreview根据需要调用方法停止。

/** Stop local video preview */
engine.stopPreview();
  • 1
  • 2

要停止播放远程音频或视频流,请使用传递给streamID参数的相应流ID调用stopPlayingStream方法。

/** Stop playing a stream*/
engine.stopPlayingStream(streamID);
  • 1
  • 2

9. 退出房间

要退出房间,请使用传递给roomID参数的相应房间ID调用logoutRoom方法。

/** Log out of a room */
engine.logoutRoom("room1");
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/763775
推荐阅读
相关标签
  

闽ICP备14008679号