精华内容
下载资源
问答
  • ExoPlayer ExoPlayer is an application level media player for Android. It provides an alternative to Android’s MediaPlayer API for playing audio and video both locally and over the Internet. ...
  • ExoPlayer+FFMpeg软解

    千次阅读 2019-05-21 17:06:48
    概述 ExoPlayer是Google开源的Android平台媒体播放器。 它是Android的MediaPlayer API的替代品。 相比于IJKPlayer,EXOPlayer更易于拓展,功能更多,bug更少。ExoPlayer虽然不支持软解但是...1.下载NDK(要下载NDK...

    概述
    ExoPlayer是Google开源的Android平台媒体播放器。 它是Android的MediaPlayer API的替代品。
    相比于IJKPlayer,EXOPlayer更易于拓展,功能更多,bug更少。ExoPlayer虽然不支持软解但是为开发者扩展软解预留了接口。
    网上竟然搜不到ExoPlayer+软解的扩展实现,那就有必要来一篇了hhh。

    预先准备:
    1.下载NDK(要下载NDK r15c,高版本编译不过)
    https://developer.android.com/ndk/downloads?hl=zh-cn
    2.下载EXO源码
    git clone https://github.com/google/ExoPlayer.git
    git checkout release-v2

    添加ffmpeg软解扩展:
    1.找到这个目录ExoPlayer/extensions/ffmpeg/src/main/jni。
    在这个目录下执行如下步骤
    1.git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
    2.cd ffmpeg && git checkout release/4.0
    3.配置ffmpeg编译参数,需要添加具体的某种解码器可自行配置

    COMMON_OPTIONS="\
     --target-os=android \
        --disable-static \
        --enable-shared \
        --disable-doc \
        --disable-programs \
        --disable-everything \
        --disable-avdevice \
        --disable-avformat \
        --disable-swscale \
        --disable-postproc \
        --disable-avfilter \
        --disable-symver \
        --disable-swresample \
        --enable-avresample \
        --enable-decoder=vorbis \
        --enable-decoder=opus \
        --enable-decoder=flac \
        --enable-decoder=alac \
        --enable-decoder=pcm_mulaw \
        --enable-decoder=pcm_alaw \
        --enable-decoder=mp3 \
        --enable-decoder=amrnb \
        --enable-decoder=amrwb \
        --enable-decoder=aac \
        --enable-decoder=ac3 \
        --enable-decoder=eac3 \
        --enable-decoder=dca \
        --enable-decoder=mlp \
        --enable-decoder=truehd \
    

    4.根据要编译的架构编写编译脚本

    ANDROID_NDK=/Users/hawkswang/ndk/android-ndk-r15c
    HOST_PLATFORM=darwin-x86_64
    ./configure \
        --libdir=android-libs/armeabi-v7a \
        --arch=arm \
        --cpu=armv7-a \
        --cross-prefix="${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/${HOST_PLATFORM}/bin/arm-linux-androideabi-" \
        --sysroot="${ANDROID_NDK}/platforms/android-9/arch-arm/" \
        --extra-cflags="-march=armv7-a -mfloat-abi=softfp" \
        --extra-ldflags="-Wl,--fix-cortex-a8" \
        --extra-ldexeflags=-pie \
        ${COMMON_OPTIONS} \
    

    5.开始编译
    make -j4 && make install-libs

    执行完步骤5就可以看到在ffmpeg目录下生成了如图.so
    [外链图片转存失败(img-wRGeZWlD-1563458349062)(http://km.oa.com/files/photos/pictures//20190326//1553572014_31.png)]

    6.编写JNI(如果想要扩展更多功能的话)

    7.交叉编译JNI接口
    在目录下ExoPlayer/extensions/ffmpeg/src/main/jni
    执行

    ANDROID_NDK=/Users/hawkswang/ndk/android-ndk-r15c
    HOST_PLATFORM=darwin-x86_64
    ${ANDROID_NDK}/ndk-build APP_ABI="armeabi armeabi-v7a arm64-v8a" -j4
    

    [外链图片转存失败(img-lhDICtUo-1563458349065)(http://km.oa.com/files/photos/pictures//20190326//1553572387_41.png)]
    执行完7步骤即会在出现如图.so

    8.在Java层初始化播放器的时候传人EXTENSION_RENDERER_MODE_PREFER即使用扩展的软解进行解码。
    [外链图片转存失败(img-phT5JiH0-1563458349065)(http://km.oa.com/files/photos/pictures//20190326//1553580223_93.png)]

    下面是把第1~5部整合到一块的脚本;

    #!/bin/bash
    ANDROID_NDK=/Users/hawkswang/ndk/android-ndk-r15c
    HOST_PLATFORM=darwin-x86_64
    COMMON_OPTIONS="\
        --target-os=android \
        --disable-static \
        --enable-shared \
        --disable-doc \
        --disable-programs \
        --disable-everything \
        --disable-avdevice \
        --disable-avformat \
        --disable-swscale \
        --disable-postproc \
        --disable-avfilter \
        --disable-symver \
        --disable-swresample \
        --enable-avresample \
        --enable-decoder=vorbis \
        --enable-decoder=opus \
        --enable-decoder=flac \
        --enable-decoder=alac \
        --enable-decoder=pcm_mulaw \
        --enable-decoder=pcm_alaw \
        --enable-decoder=mp3 \
        --enable-decoder=amrnb \
        --enable-decoder=amrwb \
        --enable-decoder=aac \
        --enable-decoder=ac3 \
        --enable-decoder=eac3 \
        --enable-decoder=dca \
        --enable-decoder=mlp \
        --enable-decoder=truehd \
        " && \
    #(git -C ffmpeg pull || git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg) && \
    cd ffmpeg && git checkout release/4.0 && \
    ./configure \
        --libdir=android-libs/armeabi-v7a \
        --arch=arm \
        --cpu=armv7-a \
        --cross-prefix="${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/${HOST_PLATFORM}/bin/arm-linux-androideabi-" \
        --sysroot="${ANDROID_NDK}/platforms/android-9/arch-arm/" \
        --extra-cflags="-march=armv7-a -mfloat-abi=softfp" \
        --extra-ldflags="-Wl,--fix-cortex-a8" \
        --extra-ldexeflags=-pie \
        ${COMMON_OPTIONS} \
        && \
    make -j4 && make install-libs && \
    make clean && ./configure \
        --libdir=android-libs/arm64-v8a \
        --arch=aarch64 \
        --cpu=armv8-a \
        --cross-prefix="${ANDROID_NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/${HOST_PLATFORM}/bin/aarch64-linux-android-" \
        --sysroot="${ANDROID_NDK}/platforms/android-21/arch-arm64/" \
        --extra-ldexeflags=-pie \
        ${COMMON_OPTIONS} \
        && \
    make -j4 && make install-libs && \
    make clean && ./configure \
        --libdir=android-libs/armeabi \
        --arch=arm \
        --cpu=armv5 \
        --cross-prefix="${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/${HOST_PLATFORM}/bin/arm-linux-androideabi-" \
        --sysroot="${ANDROID_NDK}/platforms/android-9/arch-arm/" \
        --extra-cflags="-march=armv5 -mfloat-abi=softfp" \
        --extra-ldflags="-Wl,--fix-cortex-a8" \
        --extra-ldexeflags=-pie \
        ${COMMON_OPTIONS} \
        && \
    make -j4 && make install-libs && \
    make clean
    
    echo "Success !"
    
    展开全文
  • ExoPlayer网速估计方法

    千次阅读 2018-07-31 20:21:41
    ExoPlayer是根据以往的下载速度来估计当前的网速 现介绍一下几个符号: 采样数组定义如下: private final ArrayList<Sample> samples; 上述采样数组用于存储历史采样点。 采样...

    VLC网速估计算法
    ExoPlayer是根据以往的下载速度来估计当前的网速

    现介绍一下几个符号:

    采样数组定义如下:

    private final ArrayList<Sample> samples;

    上述采样数组用于存储历史采样点。

    采样点定义如下:

    private static class Sample {
    
        public int index;
        public int weight;
        public float value;
    
    }

    index存储的是当前采样点在采样数组的索引,它是用来还原采样数组顺序用的,可以忽略
    weight存储的是每次下载数据大小的平方根,下载数据的单位是byte
    value存储的是每次下载的速度,单位是bit/s(bps)

    网速估计的过程

    1.采样点的添加方法

    • 每下载一次数据,生成一个Sample,权重weight为每次下载到的数据的Bytes数的平方根;value为每次下载数据的bps

    • 将Sample按照时间顺序加入采样数组samples里

    • 采样数组samples的大小定义为totalWeight,totalWeight是所有采样点Sample中weight的和(注意这里采样数组大小的定义,不是以往的按照采样点来定义的),这个大小有个上限定义为maxWeight=2000

    • 当加入当前采样点后,如果totalWeight>maxWeight,把最先加入采样数组的sample移除,直到totalWeight<=maxWeight

    2.网速估计方法:

    • 将采样数组按照采样点中的value值从小到大排序

    • 定义一个desiredWeight,desiredWeight=totalWeight/2

    • 从头遍历排序完的采样数组(从小value开始),依次累加各个样本的weight值,当累加值大于等于desiredWeight时,此时对应的value值为估计的网速。如果此时累加所有的采样点的值仍小于desiredWeight时,返回最近采样点的value值。

    原理文档

    其网速估计类名为SlidingPercetile.java,官网给出了该算法的原理链接,Wiki: Moving average, Wiki: Selection algorithm

    个人理解

    其实ExoPlayer的网速估计算法类似于移动平均,但是又不完全相同,没找到具体的讲ExoPlayer网速估计的算法文章了。个人理解,是这样的,假设每次下载的片段大小时一样的,那么这时候取的网速其实是所有网速的一个中位数,这样就去除了大值和小值的影响,这样预测出来的网速准确性未知,毕竟没找到相应的文章写这个算法的网速预测结果。

    网速估计获取

    上述Sample中的weight和value在ExoPlayer中按照如下方法计算所得:

    • DefaultBandwidthMeter::onTransferStart()用于记录下载起始时间sampleStartTimeMs。在DefaultHttpDataSource::open()调用(每次下载数据起始)
    • DefaultBandwidthMeter::onBytesTransferred()用于记录下载的总字节数sampleBytesTransferred。在DefaultHttpDataSource::read()中调用。
    • DefaultBandwidthMeter::onTransferEnd(),记录下载结束时间,同时生成本次下载过程的Sample(权重和bps),加入采样数组中,并调用上面的算法计算出当前的bitrateEstimate;最后清零sampleBytesTransferred,准备计算下个Sample。在DefaultHttpDataSource::close() 中调用。

    注意:播放列表和音视频数据下载的Sample都会统计到计算中。

    这一步完成之后,会得到当前的估计网速,bitrateEstimate。

    展开全文
  • ExoPlayer的简单demo

    千次阅读 2019-07-10 11:12:28
    下载地址 点击下载demo 横屏效果 package qingyunbomei.com.xingtest.videos; import android.content.pm.ActivityInfo; import android.graphics.Color; im...

    https://blog.csdn.net/qq_33582129/article/details/66975461

     

    下载地址
    点击下载demo

    横屏效果

    package qingyunbomei.com.xingtest.videos;

    import android.content.pm.ActivityInfo;
    import android.graphics.Color;
    import android.media.session.PlaybackState;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.support.constraint.ConstraintLayout;
    import android.support.v7.app.AppCompatActivity;
    import android.util.DisplayMetrics;
    import android.view.KeyEvent;
    import android.view.TextureView;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.SeekBar;
    import android.widget.TextView;

    import com.google.android.exoplayer2.DefaultLoadControl;
    import com.google.android.exoplayer2.ExoPlaybackException;
    import com.google.android.exoplayer2.ExoPlayer;
    import com.google.android.exoplayer2.ExoPlayerFactory;
    import com.google.android.exoplayer2.LoadControl;
    import com.google.android.exoplayer2.SimpleExoPlayer;
    import com.google.android.exoplayer2.Timeline;
    import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
    import com.google.android.exoplayer2.extractor.ExtractorsFactory;
    import com.google.android.exoplayer2.source.ExtractorMediaSource;
    import com.google.android.exoplayer2.source.MediaSource;
    import com.google.android.exoplayer2.source.TrackGroupArray;
    import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
    import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
    import com.google.android.exoplayer2.trackselection.TrackSelection;
    import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
    import com.google.android.exoplayer2.trackselection.TrackSelector;
    import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
    import com.google.android.exoplayer2.upstream.DataSource;
    import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
    import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
    import com.google.android.exoplayer2.util.Util;

    import java.lang.ref.WeakReference;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;

    import butterknife.BindView;
    import butterknife.ButterKnife;
    import qingyunbomei.com.xingtest.R;
    import qingyunbomei.com.xingtest.utils.PixelUtil;
    import qingyunbomei.com.xingtest.utils.TimeUtils;

    public class VideoActivity extends AppCompatActivity {

        @BindView(R.id.simpleExoPlayerView)
        SimpleExoPlayerView simpleExoPlayerView;
        @BindView(R.id.texture_view)
        TextureView textureView;
        @BindView(R.id.start_play)
        ImageView startPlay;
        @BindView(R.id.already_player_time)
        TextView alreadyPlayerTime;
        @BindView(R.id.seek_bar)
        SeekBar seekBar;
        @BindView(R.id.all_player_time)
        TextView allPlayerTime;
        @BindView(R.id.all_screen)
        ImageView allScreen;
        @BindView(R.id.constraintLayout)
        ConstraintLayout constraintLayout;
        @BindView(R.id.play_linear)
        LinearLayout playLinear;

        private static final int UP_TIME = 0;//更新播放时间
        private boolean screenFlag = false;//全屏标记
        private SimpleExoPlayer player;
        private boolean playFlag = false;//播放状态
        private ExecutorService executors = Executors.newSingleThreadExecutor();
        private final MyHandler myHandler = new MyHandler(this);

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_video);
            ButterKnife.bind(this);
            initVideo();
        }

        //初始化视频
        private void initVideo() {
            //create a TrackSelector 选择MediaSource
            DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
            //从MediaSource中选出media提供给可用的Render S来渲染,在创建播放器时被注入
            TrackSelection.Factory videoTrackSelectionFactor = new AdaptiveTrackSelection.Factory(bandwidthMeter);
            TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactor);
            //Create a default LoadControl 控制MediaSource缓存media
            LoadControl loadControl = new DefaultLoadControl();
            //Create the player
            player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);

            //produces DataSource instances through which media data is loaded
            DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
                    Util.getUserAgent(this, "飞星"), bandwidthMeter);
            //Produces Extractor instances for parsing the media data 萃取剂
            ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
            MediaSource videoSource = new ExtractorMediaSource(Uri.parse("http://w5.dwstatic.com/54/3/1622/2166193-100-1464903053.mp4"),
                    dataSourceFactory, extractorsFactory, null, null);
            //设置资源
            player.prepare(videoSource);

            //显示字幕
    //        player.setTextOutput(new TextRenderer.Output() {
    //            @Override
    //            public void onCues(List<Cue> cues) {
    //
    //            }
    //        });
            player.addListener(eventListener);
            player.setVideoTextureView(textureView);

    //        simpleExoPlayerView.setPlayer(player);

        }

        //播放事件监听
        private ExoPlayer.EventListener eventListener = new ExoPlayer.EventListener()
        {
            @Override
            public void onTimelineChanged(Timeline timeline, Object manifest)
            {
                System.out.println("播放: onTimelineChanged 周期总数 " + timeline);
            }

            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
                System.out.println("播放: TrackGroupArray  ");
            }

            @Override
            public void onLoadingChanged(boolean isLoading) {
                System.out.println("播放: onLoadingChanged  " + TimeUtils.secToTime((int) (player.getBufferedPosition() / 1000)));
                //设置二级进度条
                seekBar.setSecondaryProgress((int) (player.getBufferedPosition() / 1000));
            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                switch (playbackState) {
                    case PlaybackState.STATE_PLAYING:
                        //初始化播放点击事件并设置总时长
                        initPlayVideo();
                        System.out.println("播放状态: 准备 playing");
                        break;

                    case PlaybackState.STATE_BUFFERING:
                        System.out.println("播放状态: 缓存完成 playing");
                        break;

                    case PlaybackState.STATE_CONNECTING:
                        System.out.println("播放状态: 连接 CONNECTING");
                        break;

                    case PlaybackState.STATE_ERROR://错误
                        System.out.println("播放状态: 错误 STATE_ERROR");
                        break;

                    case PlaybackState.STATE_FAST_FORWARDING:
                        System.out.println("播放状态: 快速传递");
                        pausePlay();//暂停播放
                        break;

                    case PlaybackState.STATE_NONE:
                        System.out.println("播放状态: 无 STATE_NONE");
                        break;

                    case PlaybackState.STATE_PAUSED:
                        System.out.println("播放状态: 暂停 PAUSED");
                        break;

                    case PlaybackState.STATE_REWINDING:
                        System.out.println("播放状态: 倒回 REWINDING");
                        break;

                    case PlaybackState.STATE_SKIPPING_TO_NEXT:
                        System.out.println("播放状态: 跳到下一个");
                        break;

                    case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
                        System.out.println("播放状态: 跳到上一个");
                        break;

                    case PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM:
                        System.out.println("播放状态: 跳到指定的Item");
                        break;

                    case PlaybackState.STATE_STOPPED:
                        System.out.println("播放状态: 停止的 STATE_STOPPED");
                        break;
                }
            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {
                System.out.println("播放: onPlayerError  ");
            }

            @Override
            public void onPositionDiscontinuity() {
                System.out.println("播放: onPositionDiscontinuity  ");
            }
        };

        //初始化播放事件
        private void initPlayVideo()
        {
            allPlayerTime.setText(TimeUtils.secToTime((int) (player.getDuration() / 1000)));
            //设置总时长
            seekBar.setMax((int) (player.getDuration() / 1000));
            seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
            {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {}

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                    //是暂停的开始播放
                    if (!player.getPlayWhenReady()) {
                        continuePlay();//继续播放
                    }
                    player.seekTo(seekBar.getProgress() * 1000);
                }
            });

            //播放按钮
            startPlay.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (player.getPlayWhenReady()) {
                        pausePlay();//暂停播放
                    } else {
                        continuePlay();//继续播放
                    }
                }
            });

            //全屏切换
            allScreen.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v) {
                    if (screenFlag)//是全屏
                    {
                        setHalfScreen();
                    } else {
                        screenFlag = true;//设置为全屏
                        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                        //设置控件大小
                        ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) textureView.getLayoutParams();
                        params.width = ConstraintLayout.LayoutParams.MATCH_PARENT;
                        System.out.println("屏幕: 控件 : " + constraintLayout.getHeight());
                        params.height = getHeight();
                        params.dimensionRatio = 0f;
                        playLinear.setPadding(0,0,0, PixelUtil.dp2px(VideoActivity.this,25));
                        textureView.setLayoutParams(params);
                    }
                }
            });
        }

        //设置为半屏
        private void setHalfScreen()
        {
            screenFlag = false;//设置为半屏
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            //设置控件大小
            ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) textureView.getLayoutParams();
            params.width = ConstraintLayout.LayoutParams.MATCH_PARENT;
            params.dimensionRatio = 1.6f;
            playLinear.setPadding(0,0,0,0);
            textureView.setLayoutParams(params);
        }


        //暂停播放
        private void pausePlay() {
            player.setPlayWhenReady(false);
            startPlay.setBackgroundColor(Color.WHITE);
            playFlag = false;
        }

        //继续播放
        private void continuePlay()
        {
            player.setPlayWhenReady(true);
            startPlay.setBackgroundColor(Color.RED);
            //开始读取进度
            playFlag = true;
            executors.execute(runnable);
        }

        private static class MyHandler extends Handler
        {
            private final WeakReference<VideoActivity> mActivity;
            private MyHandler(VideoActivity mActivity)
            {
                this.mActivity = new WeakReference<>(mActivity);
            }
            @Override
            public void handleMessage(Message msg) {
                if (mActivity.get() == null)
                {
                    return;
                }
                if (msg.what == UP_TIME) {
                    //设置播放进度
                    VideoActivity videoActivity = mActivity.get();
                    videoActivity.seekBar.setProgress(msg.arg1);
                    videoActivity.alreadyPlayerTime.setText(TimeUtils.secToTime(msg.arg1));
                }
            }
        }

        //开启线程读取进度
        private Runnable runnable = new Runnable() {
            @Override
            public void run() {

                while (playFlag) {
                    Message msg = new Message();
                    msg.what = UP_TIME;
                    //获取播放时间
                    msg.arg1 = (int) (player.getCurrentPosition() / 1000);
                    myHandler.sendMessage(msg);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };


        @Override
        protected void onDestroy() {
            super.onDestroy();
            //释放资源
            if (player != null) {
                playFlag = false;//停止线程
                executors.shutdown();
                player.stop();
                player.release();
                player = null;
            }
            myHandler.removeCallbacksAndMessages(null);
        }

        //获取屏幕高度
        private int getHeight() {
            DisplayMetrics dm = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(dm);
            return dm.heightPixels;
        }

        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK &&
                    getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
            {
                //设置半屏
                setHalfScreen();
            }
            return super.onKeyDown(keyCode, event);
        }
    }


    --------------------- 
    作者:飞yu流星 
    来源:CSDN 
    原文:https://blog.csdn.net/qq_33582129/article/details/66975461 
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • ExoPlayer的google官方下载地址: https://github.com/google/ExoPlayer      

    ExoPlayer的google官方下载地址:

    https://github.com/google/ExoPlayer

     

     

     

    展开全文
  • 最近在研究google的ExoPlayer,根据项目需求,需要获得当前帧的显示时间,看源码发现解码在MediaCodecVideoRenderer这个类中执行解码,发现processOutputBuffer函数内有时间数据,根据测试知道presentationTimeUs是...
  • exoplayer主要针对网络自适应流进行播放,从官方文档我们了解到,exoplayer支持的网络自适应流包括DASH、HLS和SmoothStreaming,下面对网络自适应流做一个简单介绍。 二、DASH流简介: DASH流是基于HTTP的动态自适应...
  • https://blog.csdn.net/liosen/article/details/83896721 该文章的demo下载
  • 一、exoplayer的相关库的集成关联 1.1 关联的方法有两种,第一种是常规的远程依赖From JCenter 本人的是as3.1。我这里的exo库用的是2.8.0。取消其他版本的点这里:历代exoplayer-release版本简介。 1.2第二种关联...
  • 一、基于ExoPlayer 自定义播放器 JPlayer支持功能: 1 ExoUserPlayer 基本播放。 2 GestureVideoPlayer 增加手势 亮度,音量,快进,等手势。 3 ManualPlayer 可自定义触发播放。 5 广告视频...
  • ------ demo下载 ------ 特性 支持直播和点播。 支持调整显示比例:默认、原始大小、16:9、4:3、铺满屏幕、居中裁剪。 支持滑动调节播放进度、声音、亮度;双击播放、暂停;保存播放进度。 支持边播边缓存,使用了...
  • 开发中有个需求是需要播放下载到本地的视频,用exoplayer框架放的 然后有机器极小概率出现严重卡顿现象,调查的时候发现cpu内存都是正常的,下面有一些卡顿的时候抓的日志: W/AudioFlinger( 147): write blocked ...
  • VLC Media PlayerVLC 是VideoLAN 计划所研发的工程,最早预1996年开始,是一个完全的跨平台...目前累计下载13亿次,是真真正正的全球播放器;VLC的整体框架是设计成一套module的管理机制,将功能分类并抽象成modules...
  • English | 简体中文 ArtPlayer ...下载 Demo Download 开始使用 build.gradle dependencies { // required implementation 'org.salient.artvideoplayer:artplayer-java:0.6.0' // Default c
  • 传统的VR显示设备主要为PC端的,目前出现了很多基于Android的VR一体机显示设备. 但如果在Android端VR设备上直接安装普通的RTMP/HLS/DASH实时流播放器,渲染的视频仍旧显示在一个平面上,而...1. exoplayer 下载解码 RTM...
  • 正常下载, 开着app一直下载完的话就可以播放,下载配置的单线程下载 是不是下载进度没有记录好 继续接着下载的时候损坏了视频文件的索引导致视频无法播放?</p><p>该提问来源于开源项目:AriaLyy/Aria</p></...
  • 目前累计下载13亿次,是真真正正的全球播放器; VLC的整体框架是设计成一套module的管理机制,将功能分类并抽象成modules。 VLC main: player的main。初始化libVLC 并加载用户界面。 libVLCcore:lib
  • ExoPlayer 要播放 flac 音频,是需要自己编译 so 的,具体怎么操作可以看 ExoPlayer 的 github,本项目已经把编译好的代码放在了 extension-flac2120 这个 module 里面,2120 代表 版本号是 2.12.0。大家可以通过...
  • 手势指导页面(有些播放器有新手指导功能),离线下载的界面(该界面中包含下载列表, 列表的item编辑(全选, 删除)) 用户从wifi切换到4g网络,提示网络切换弹窗界面(当网络由wifi变为4g的时候会显示) 图片广告视图(带有...
  • Version 4.0.0 now requires Android target SDK 26+ and Gradle 3 plugin in order to support ExoPlayer 2.9.0. Google is dropping support for apps using target SDKs older than 26 as of October 2018 and ...
  • 基于IJKPlayer(兼容系统MediaPlayer与EXOPlayer2),实现了多功能的视频播放器。 (请仔细阅读下方各项说明,大多数问题可在下方找到解答)。 如果克隆太慢或者图片看不到,可尝试从码云地址下载 类型 功能 ...
  • Java按行读取InputStream,并提取出int。

    千次阅读 2019-11-05 22:59:04
    下面以ExoPlayer下载流为例,下载一个txt文件,读取它的内容,并将有效的数据提取出来。 DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec); try { inputStream.open(); ....
  • android 使用OpenGL Shaders渲染EXOPlayer视频 源码下载:http://www.dandroid.cn/?p=2661 android文件下载管理源码 源码下载:http://www.dandroid.cn/?p=2665 android视频播放器完美切换全屏...
  • # ExoPlayer as IMediaPlayer: optional, experimental compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8' } iOS in coming... My Build Environment Common Mac OS X 10.11.5 Android NDK r10e Android ...
  • SRS SRS/3.0,OuXuli,是一个流媒体集群,支持RTMP/HLS/WebRTC/SRT/GB28181,高效、稳定、易用,简单而快乐。 SRS is a RTMP/HLS/WebRTC/SRT/GB28181 streaming cluster, high efficiency, stable and simple. ...
  • SRS(Simple Realtime Server) ... ... Remark: Although SRS is licenced under MIT, but there are some depended libraries which are distributed using their own licenses, please read License Mixing. ...

空空如也

空空如也

1 2
收藏数 39
精华内容 15
关键字:

exoplayer下载