快速集成一个视频直播功能

版权声明:本文为博主原创文章,未经博主允许不得转载。邮箱[email protected]。 https://blog.csdn.net/pangpang123654/article/details/78012706

前言

前段时间的工作安排,需要做一个视频监控的功能,其实就是采用 m3u8 做一个直播。

确定需求后进行了一堆调研,最后在B站的 ijkplayer 与 Google 的 ExoPlayer 中做出了选择,对于为啥选择了 ExoPlayer ,后面会做具体分析,目前先留点悬念,目前根据选择 ExoPlayer,从最初调研到集成成功打算做一个专题,分别从众多框架中为何选择了 ExoPlayer、硬解码与软解码的区别和对比、自定义 ExoPlayer、集成中所遇到的坑、源码分析,作为开头第一篇,目前只是一篇短暂的集成,并附上大量的注释,具体不做太多分析。

项目相关地址

ExoPlayer 源码地址:https://github.com/google/ExoPlayer

ExoPlayer api地址:http://google.github.io/ExoPlayer/doc/reference/

ExoPlayer 开发者指南:https://google.github.io/ExoPlayer/guide.html

优点和缺点

相比 Android 内置的 MediaPlayer,ExoPlayer 具有许多优于优势:

  • 支持 Dynamic Adaptive Streaming over HTTP (DASH) 和SmoothStreaming进行动态自适应流,这两种都不受 MediaPlayer 支持,还支持许多其它格式。有关详细信息,请参考开发者指南。
  • 支持高级 HLS 功能,如正确处理 #EXT-X-DISCONTINUITY的标签。
  • 能够无缝融合,连接和循环媒体资源。
  • 自定义和扩展播放器以适应您的用例的能力。 ExoPlayer专门设计了这一点,并允许许多组件被替换为自定义实现。
  • 轻松更新播放器与您的应用程序。 因为 ExoPlayer 是您的应用程序apk中包含的库,所以您可以控制使用哪个版本,你可以轻松地将其更新为常规应用程序更新的一部分。
  • 设备通用性更强。
  • 支持在Android 4.4(API级别19)以上的Widevine通用加密。

需要注意的是,也有一些缺点,这一点很重要:

  • ExoPlayer的标准音频和视频部件依赖于Android的 MediaCodecAPI,MediaCodecAPI 在搭载Android 4.1(API级别16)发布。因此,他们不会在较早版本的 Android 的工作。Widevine 的通用加密可以在 Android 4.4(API级别19)和更高。

附上原文

Pros and cons

ExoPlayer has a number of advantages over Android’s built in MediaPlayer:
  • Support for Dynamic Adaptive Streaming over HTTP (DASH) and SmoothStreaming, neither of which are supported by MediaPlayer. Many other formats are also supported. See the Supported formats page for details.
  • Support for advanced HLS features, such as correct handling of#EXT-X-DISCONTINUITY tags.
  • The ability to seamlessly merge, concatenate and loop media.
  • The ability to update the player along with your application. Because ExoPlayer is a library that you include in your application apk, you have control over which version you use and you can easily update to a newer version as part of a regular application update.
  • Fewer device specific issues and less variation in behavior across different devices and versions of Android.
  • Support for Widevine common encryption on Android 4.4 (API level 19) and higher.
  • The ability to customize and extend the player to suit your use case. ExoPlayer is designed specifically with this in mind, and allows many components to be replaced with custom implementations.
  • The ability to quickly integrate with a number of additional libraries using official extensions. For example the IMA extension makes it easy to monetize your content using the Interactive Media Ads SDK.

It’s important to note that there are also some disadvantages:

  • ExoPlayer’s standard audio and video components rely on Android’sMediaCodec API, which was released in Android 4.1 (API level 16). Hence they do not work on earlier versions of Android. Widevine common encryption is available on Android 4.4 (API level 19) and higher.

**

支持的格式

**

ExoPlayer支持播放DASH,SmoothStreaming和HLS自适应流,以及如MP4,M4A,FMP4,WebM,MKV,MP3,Ogg,WAV,MPEG-TS,MPEG-PS,FLV和ADTS (AAC)。

集成

先上代码在做分析,首先导入ExoPlayer需要的包:

compile 'com.google.android.exoplayer:exoplayer:r2.4.1'

xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/player_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="true" />

是的,就这么短,Google考虑得很全面,提供了exoplayer2-ui的包,给开发者省去了很多事情。

核心代码如下:

/**
 * 播放器页面
 *
 * Created by Zero on 2017/9/16.
 */
public class ExoPlayerActivity extends AppCompatActivity {


    @BindView(R.id.player_view)
    SimpleExoPlayerView playerView;
    private SimpleExoPlayer player;

    /**
     * 网上找的一个m3u8地址
     */
    private static  final String url = "http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_exo_player);
        ButterKnife.bind(this);
        initPlayer();
    }
    private void initPlayer(){
        /**
         * Provides estimates of the currently available bandwidth.
         */
        BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        /**
         * TrackSelector用来选择磁道,由MediaSource所提供,并会被任意的可用的Renderers所使用,当播放器被创建时,TrackSelector会被注入.
         */
        TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

        /**
         * SimpleExoPlayer单例
         */
        player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);
        /**
         * 设置用户控制,其实就是屏幕上的功能按钮,默认显示,false则不显示,设置false后可自定义
         *
         * 源码中:Sets whether the playback controls can be shown. If set to {@code false} the playback controls
         * are never visible and are disconnected from the player.
         *
         * @param useController Whether the playback controls can be shown.
         */
        playerView.setUseController(true);
        playerView.requestFocus();

        /**
         * 将播放器添加到视图
         */
        playerView.setPlayer(player);

        Uri uri =Uri.parse(url);
        /**
         * Estimates bandwidth by listening to data transfers
         */
        DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
        /**
         * PS:
         * DefaultUriDataSource - 用于播放本地和网络媒体;
         * AssetDataSource - 用于播放应用中assets文件夹下的媒体。
         */
        DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "ExoPlayerDemo"), bandwidthMeterA);
        /**
         * ExoPlayer每帧是通过MediaSource展示的,播放的每一帧必须先创建对应的MediaSource
         *
         * MediaSource 定义了加载、播放媒体,并且可以读取已经加载的媒体,使用ExoPlayer.prepare 可在播放开始传入MediaSource
         */
        MediaSource videoSource = new HlsMediaSource(uri, dataSourceFactory, 1, null, null);
        /**
         * 无缝循环播放视频
         */
        LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);

        player.prepare(loopingSource);
        /**
         * 开始播放
         */
        player.setPlayWhenReady(true);
    }
}

就这么简单?是的,现在一个播放器就这么搞定了,亲测可以,来张图证明下:
这里写图片描述

好了,就这么搞定一个 m3u8 格式的视频直播,上述也说了,支持的格式很多,可根据不同的格式做出相应的处理,主要是对MediaSource(DashMediaSource),SmoothStreaming(SsMediaSource),HLS(HlsMediaSource)和常规的媒体文件(ExtractorMediaSource)做出相应的处理,在此不做多余的赘述,敬请期待,^_^。

友情推荐:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/pangpang123654/article/details/78012706
今日推荐