【问题标题】:Exoplayer playing m3u8 files AndroidExoplayer 播放 m3u8 文件 Android
【发布时间】:2015-10-03 18:28:42
【问题描述】:

在尝试了多种使用 videoview 和 mediaplayer 播放 m3u8 文件的方法后,我决定放弃。每次我播放 m3u8 文件时,我只听到声音。(请不要从堆栈溢出中写 url 来回答我的问题。我把它们都红了) 四处打听,终于知道exoplayer也许就是我要找的那个。但是 exoplayer 似乎是一个新手,我找不到任何合适的教程。据说我自己是一个新手,所有关于跟踪器和 blabla 的讨论对我来说似乎都太复杂了。我只想能够从我的应用程序中的不同 url 打开我所有的 m3u8 文件而不将它们传递给 vlc 或任何外部意图。

为了记录,我使用 KitKat 及更高版本。所以exoplayer应该是可以实现的。

所以我迫切需要的是一个简单的教程,教我如何使用 exoplayer 播放我的 m3u8 文件 或任何其他显示视频和播放音频的方式,只是其中之一。请不要将我链接到 google dev 上的 exoplayer 页面。我也去过。

提前致谢:)

【问题讨论】:

  • 有人吗?帮助?我会喜欢它

标签: android android-mediaplayer m3u8 exoplayer


【解决方案1】:

在 Android 4.1+ 上,您可以使用这个库 https://github.com/brianwernick/ExoMedia/ 。自述页面上提到的示例应该足以让您入门。我已经复制了该代码 sn-p 并进行了一些添加/修改。

            private void setupVideoView() {
                EMVideoView emVideoView = (EMVideoView)findViewById(R.id.video_play_activity_video_view);
                emVideoView.setOnPreparedListener(this);

                //Enter your m3u8 URL below
                emVideoView.setVideoURI(Uri.parse("http://SOMESERVER/playlist.m3u8"));
            }

            @Override
            public void onPrepared(MediaPlayer mp) {
                //Starts the video playback as soon as it is ready
                emVideoView.start();
            }

            @Override
            public void onPause() {
                super.onPause();
                //Pause Video Playback
                emVideoView.pause();
            }

【讨论】:

    【解决方案2】:

    我创建了一个演示应用程序来播放 m3u8 媒体文件

    首先将 gradle 依赖项添加到您的文件中

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

    使用存储 master.m3u8 路径作为输入和 SimpleExoPlayerView 视图创建一个简单的布局文件以播放下载的文件。

     <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout mlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent" android:layout_height="match_parent">
    
    <android.support.design.widget.TextInputEditText
      android:layout_marginTop="15dp"
    android:layout_width="match_parent"
       android:id="@+id/mediaPath"
       android:layout_height="56dp" />
       <android.support.v7.widget.AppCompatButton
    android:id="@+id/play"
           android:layout_marginLeft="50dp"
    android:layout_marginRight="50dp"
           android:layout_below="@+id/mediaPath"
           android:background="@color/colorAccent"
    android:layout_width="match_parent"
    android:text="Play"
    android:layout_height="56dp" />
    <com.google.android.exoplayer2.ui.SimpleExoPlayerView
       android:layout_below="@+id/play"
       android:id="@+id/video_view"
       android:layout_marginTop="5dp"
       android:layout_width="match_parent"
       android:layout_height="match_parent"/>
    </RelativeLayout>
    

    创建一个简单的 ExoPlayer Activity 来播放文件。

    public class ExoPlayer  extends AppCompatActivity{
    Context mContext;
    SimpleExoPlayerView playerView;
    EditText editText;
    private ComponentListener componentListener;
    private DataSource.Factory mediaDataSourceFactory;
    private Handler mainHandler;
    private DefaultTrackSelector trackSelector;
    SimpleExoPlayer player;
    private static final DefaultBandwidthMeter BANDWIDTH_METER = new        DefaultBandwidthMeter();
    
    
    
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_exoplayer);
       mContext =this;
       editText = (EditText) findViewById(R.id.mediaPath);
       Button btnPlay = (Button) findViewById(R.id.play);
       playerView  = (SimpleExoPlayerView)findViewById(R.id.video_view);
       mediaDataSourceFactory = buildDataSourceFactory(true);
       mainHandler = new Handler();
       componentListener = new ComponentListener();
       trackSelector = new DefaultTrackSelector();
       btnPlay.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
          if(editText.getText()!=null && editText.getText().length()>0){
                   initializePlayer(editText.getText().toString());
               }
           }
       });
    }
       private DataSource.Factory buildDataSourceFactory(boolean useBandwidthMeter) {
       return ((AnalyticsApplication) getApplication())
               .buildDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null);
     }
    
       private void initializePlayer(String path) {
       player = ExoPlayerFactory.newSimpleInstance(mContext, trackSelector);
       player.addListener(componentListener);
    //        String path = file:///storage/emulated/0/SugarBox/master.m3u8";
       Uri uri = Uri.parse(path);
       MediaSource mediaSource = buildMediaSource(uri);
       player.prepare(mediaSource, true, false);
       playerView.setPlayer(player);
     }
      private MediaSource buildMediaSource(Uri uri) {
     return new HlsMediaSource(uri, mediaDataSourceFactory, mainHandler, null);
     }
     private void releasePlayer() {
       if (player != null) {
           player.removeListener(componentListener);
           player.release();
           player = null;
       }
       }
    
    
    
     @Override
     public void onStart() {
       super.onStart();
       if (Util.SDK_INT > 23) {
           if(editText.getText()!=null && editText.getText().length()>0){
               initializePlayer(editText.getText().toString());
           }
       }
     }
    
    
    
    
    @Override
       public void onResume() {
       super.onResume();
       if ((Util.SDK_INT <= 23 || player == null)) {
           if(editText.getText()!=null && editText.getText().length()>0){
               initializePlayer(editText.getText().toString());
           }
       }
     }
    
    
    
    @Override
     public void onPause() {
       super.onPause();
       if (Util.SDK_INT <= 23) {
           releasePlayer();
       }
    }
    
    
    
     @Override
    public void onStop() {
       super.onStop();
       if (Util.SDK_INT > 23) {
           releasePlayer();
       }
    }
    
    
    
    
    
    
    
       private class ComponentListener implements com.google.android.exoplayer2.ExoPlayer.EventListener{
    
       @Override
       public void onPlayerStateChanged(boolean playWhenReady,
                                        int playbackState) {
           String stateString;
           switch (playbackState) {
               case com.google.android.exoplayer2.ExoPlayer.STATE_IDLE:
                   stateString = "ExoPlayer.STATE_IDLE      -";
                   break;
               case com.google.android.exoplayer2.ExoPlayer.STATE_BUFFERING:
                   stateString = "ExoPlayer.STATE_BUFFERING -";
                   break;
               case com.google.android.exoplayer2.ExoPlayer.STATE_READY:
                   stateString = "ExoPlayer.STATE_READY     -";
                   break;
               case com.google.android.exoplayer2.ExoPlayer.STATE_ENDED:
                   stateString = "ExoPlayer.STATE_ENDED     -";
                   break;
               default:
                   stateString = "UNKNOWN_STATE             -";
                   break;
           }
           Log.d("ExopLayer", "changed state to " + stateString
                   + " playWhenReady: " + playWhenReady);
       }
    
       @Override
       public void onTimelineChanged(Timeline timeline, Object manifest) {}
       @Override
       public void onTracksChanged(TrackGroupArray trackGroups,
                                   TrackSelectionArray trackSelections) {}
       @Override
       public void onLoadingChanged(boolean isLoading) {}
       @Override
       public void onPlayerError(ExoPlaybackException error) {}
       @Override
       public void onPositionDiscontinuity() {}
       @Override
       public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {}
      }
    
    
    
    private DrmSessionManager<FrameworkMediaCrypto> buildDrmSessionManager(UUID uuid,   String licenseUrl, String[] keyRequestPropertiesArray) throws UnsupportedDrmException {
       if (Util.SDK_INT < 18) {
           return null;
       }
       HttpMediaDrmCallback drmCallback = new HttpMediaDrmCallback(licenseUrl,
               buildHttpDataSourceFactory(false));
       if (keyRequestPropertiesArray != null) {
           for (int i = 0; i < keyRequestPropertiesArray.length - 1; i += 2) {
               drmCallback.setKeyRequestProperty(keyRequestPropertiesArray[i],
                       keyRequestPropertiesArray[i + 1]);
           }
       }
       return new DefaultDrmSessionManager<>(uuid,
               FrameworkMediaDrm.newInstance(uuid), drmCallback, null, mainHandler, null);
     }
    
    
    
    
      private HttpDataSource.Factory buildHttpDataSourceFactory(boolean useBandwidthMeter) {
       return ((AnalyticsApplication) getApplication())
               .buildHttpDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null);
    
    
      }
    
    
    }
    

    【讨论】:

    • 我尝试了代码,但它只适用于文件类型:m3u8,对吧?我尝试使用以下 mp4 文件,但没有任何反应:w3schools.com/html/mov_bbb.mp4 我不知道如何理解 AnalyticsApplication 也是如此? in: return ((AnalyticsApplication) getApplication ()) .buildHttpDataSourceFactory (useBandwidthMeter?BANDWIDTH_METER: null);
    【解决方案3】:

    这是使用 ExoPlayer Lib 流式传输 m3u8 文件的最简单方法希望有所帮助 https://github.com/karim23/SimpleStreamPlayer/tree/master

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getApplicationContext();
        setContentView(R.layout.activity_main);
        //change the live streaming URL with yours. 
        contentUri = "http://abclive.abcnews.com/i/abc_live4@136330/index_1200_av-b.m3u8?sd=10&b=1200&rebase=on";
        // contentType = DemoUtil.TYPE_HLS;
        final Intent intent = new Intent(context, VideoPlayerActivity.class).setData(Uri.parse(contentUri))
                .putExtra(VideoPlayerActivity.CONTENT_ID_EXTRA, -1)
                //Change the type according to the live streaming extension.
                .putExtra(VideoPlayerActivity.CONTENT_TYPE_EXTRA, DemoUtil.TYPE_HLS);
        liveStreamingTv =(TextView)findViewById(R.id.mainActivity_liveStreamingTv);
        liveStreamingTv.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                startActivity(intent);
            }
        });
    }
    

    【讨论】:

      【解决方案4】:

      我使用 m3u8 使用过以下代码

          videoView = findViewById(R.id.videoViewXml);
      
          final ProgressDialog progressDialog = new ProgressDialog(VideoActivity.this);
          progressDialog.setMessage("Please Wait");
          progressDialog.setCancelable(false);
          progressDialog.show();
      
          MediaController mediaController = new MediaController(this);
          mediaController.setAnchorView(videoView);
          videoView.setMediaController(mediaController);
      
          videoView.setVideoURI(Uri.parse(VIDEO_PATH));
          videoView.start();
      
          videoView.setOnPreparedListener(new OnPreparedListener() {
              @Override
              public void onPrepared(MediaPlayer mp) {
                  progressDialog.dismiss();
              }
          });
      

      【讨论】:

        【解决方案5】:

        ExoPlayer 目前没有教程。 ExoPlayerMediaPlayer 的最佳替代品,但目前对新手不太友好。

        你要做的就是去github页面看看demo应用程序中的DemoPlayer类。

        这个应用可以打开很多不同的格式,包括hls

        【讨论】:

        • 如何使用演示?我需要将代码复制到我的应用中吗?
        【解决方案6】:

        解决播放m3u8文件时黑屏的问题,我用这个解决了,

        实现'com.google.android.exoplayer:exoplayer:2.13.3'

        媒体源代码:

            private fun buildMediaSource(uri: Uri): MediaSource {
            
                    val userAgent = "exoplayer-codelab"
            
                    return if (uri.lastPathSegment!!.contains("mp3") || uri.lastPathSegment!!.contains("mp4")) {
                        ExtractorMediaSource.Factory(DefaultHttpDataSourceFactory(userAgent))
                            .createMediaSource(uri)
                    } else {
                        HlsMediaSource.Factory(DefaultHttpDataSourceFactory(userAgent))
                            .createMediaSource(uri)
                    }
        }
        

        媒体来源:

         val mediaSource = buildMediaSource(Uri.parse(stories[counter].mediaUrl))
         simpleExoPlayer.prepare(mediaSource, false, false)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-01
          • 2023-02-03
          • 2023-03-17
          • 2023-02-03
          • 2018-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多