java - 使用 LibVLC 在 Android 应用程序上加载 m3u 播放列表失败

标签 java android android-tv libvlc m3u

我正在使用 LibVLC 测试 IPTV 应用程序,我想帮助加载和播放 m3u 播放列表,但不幸的是它没有工作。我通过最初测试在线 mp4 链接来确认播放器的工作原理,但未能使其运行。

使用库de.mrmaffen:libvlc-android:2.1.12@aar,我的播放器的代码是:

视频 Activity :

public class VideoActivity extends Activity implements IVLCVout.Callback {

    public final static String TAG = "IPTV";

    public final static String LOCATION = "com.example.android.tvleanback.ui.VideoActivity.location";

    private String mFilePath;

    // display surface
    private SurfaceView mSurface;
    private SurfaceHolder holder;

    // media player
    private LibVLC libvlc;
    private MediaPlayer mMediaPlayer = null;
    private int mVideoWidth;
    private int mVideoHeight;
    private final static int VideoSizeChanged = -1;

    /*************
     * Activity
     *************/

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sample);

        // Receive path to play from intent
        Intent intent = getIntent();
        mFilePath = intent.getExtras().getString("stream");

        Log.d(TAG, "Playing back " + mFilePath);

        mSurface = (SurfaceView) findViewById(R.id.surface);
        holder = mSurface.getHolder();
        //holder.addCallback(this);



    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setSize(mVideoWidth, mVideoHeight);
    }

    @Override
    protected void onResume() {
        super.onResume();
        createPlayer(mFilePath);
    }

    @Override
    protected void onPause() {
        super.onPause();
        releasePlayer();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releasePlayer();
    }

    /*************
     * Surface
     *************/
    private void setSize(int width, int height) {
        mVideoWidth = width;
        mVideoHeight = height;
        if (mVideoWidth * mVideoHeight <= 1)
            return;

        if(holder == null || mSurface == null)
            return;

        // get screen size
        int w = getWindow().getDecorView().getWidth();
        int h = getWindow().getDecorView().getHeight();

        // getWindow().getDecorView() doesn't always take orientation into
        // account, we have to correct the values
        boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
        if (w > h && isPortrait || w < h && !isPortrait) {
            int i = w;
            w = h;
            h = i;
        }

        float videoAR = (float) mVideoWidth / (float) mVideoHeight;
        float screenAR = (float) w / (float) h;

        if (screenAR < videoAR)
            h = (int) (w / videoAR);
        else
            w = (int) (h * videoAR);

        // force surface buffer size
        holder.setFixedSize(mVideoWidth, mVideoHeight);

        // set display size
        LayoutParams lp = mSurface.getLayoutParams();
        lp.width = w;
        lp.height = h;
        mSurface.setLayoutParams(lp);
        mSurface.invalidate();
    }

    /*************
     * Player
     *************/

    private void createPlayer(String media) {
        releasePlayer();
        try {
            if (media.length() > 0) {
                Toast toast = Toast.makeText(this, media, Toast.LENGTH_LONG);
                toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0,
                        0);
                toast.show();
            }

            // Create LibVLC
            // TODO: make this more robust, and sync with audio demo
            ArrayList<String> options = new ArrayList<String>();
            //options.add("--subsdec-encoding <encoding>");
            options.add("--aout=opensles");
            options.add("--audio-time-stretch"); // time stretching
            options.add("-vvv"); // verbosity
            options.add("--http-reconnect");
            options.add("--network-caching="+6*1000);
            libvlc = new LibVLC(this, options);
            //libvlc.setOnHardwareAccelerationError(this);
            holder.setKeepScreenOn(true);

            // Create media player
            mMediaPlayer = new MediaPlayer(libvlc);
            mMediaPlayer.setEventListener(mPlayerListener);

            // Set up video output
            final IVLCVout vout = mMediaPlayer.getVLCVout();
            vout.setVideoView(mSurface);
            //vout.setSubtitlesView(mSurfaceSubtitles);
            vout.addCallback(this);
            vout.attachViews();

            Media m = new Media(libvlc, Uri.parse(media));
            mMediaPlayer.setMedia(m);
            mMediaPlayer.play();
        } catch (Exception e) {
            Toast.makeText(this, "Error creating player!", Toast.LENGTH_LONG).show();
        }

        mSurface.getRootView().setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
                    Display display = getWindowManager().getDefaultDisplay();
                    Point size = new Point();
                    display.getSize(size);

                    Float p = event.getX()/size.x;
                    Long pos = (long) (mMediaPlayer.getLength() / p);
                    if (mMediaPlayer.isSeekable()) {
                        //mLibVLC.setTime( pos );
                        mMediaPlayer.setPosition(p);
                    } else {
                    }
                }

                return true;
            }
        });
    }

    // TODO: handle this cleaner
    private void releasePlayer() {
        if (libvlc == null)
            return;
        mMediaPlayer.stop();
        final IVLCVout vout = mMediaPlayer.getVLCVout();
        vout.removeCallback(this);
        vout.detachViews();
        holder = null;
        libvlc.release();
        libvlc = null;

        mVideoWidth = 0;
        mVideoHeight = 0;
    }

    /*************
     * Events
     *************/

    private MediaPlayer.EventListener mPlayerListener = new MyPlayerListener(this);


    public void onNewLayout(IVLCVout vout, int width, int height, int visibleWidth, int visibleHeight, int sarNum, int sarDen) {
        if (width * height == 0)
            return;

        // store video size
        mVideoWidth = width;
        mVideoHeight = height;
        setSize(mVideoWidth, mVideoHeight);
    }

    @Override
    public void onSurfacesCreated(IVLCVout vout) {

    }

    @Override
    public void onSurfacesDestroyed(IVLCVout vout) {

    }

    private static class MyPlayerListener implements MediaPlayer.EventListener {
        private WeakReference<VideoActivity> mOwner;

        public MyPlayerListener(VideoActivity owner) {
            mOwner = new WeakReference<VideoActivity>(owner);
        }

        @Override
        public void onEvent(MediaPlayer.Event event) {
            VideoActivity player = mOwner.get();
            Log.d(TAG, "Player EVENT");
            switch(event.type) {
                case MediaPlayer.Event.EndReached:
                    Log.d(TAG, "MediaPlayerEndReached");
                    player.releasePlayer();
                    break;
                case MediaPlayer.Event.EncounteredError:
                    Log.d(TAG, "Media Player Error, re-try");
                    //player.releasePlayer();
                    break;
                case MediaPlayer.Event.Playing:
                case MediaPlayer.Event.Paused:
                case MediaPlayer.Event.Stopped:
                default:
                    break;
            }
        }
    }


    public void onHardwareAccelerationError(IVLCVout vout) {
        // Handle errors with hardware acceleration
        Log.e(TAG, "Error with hardware acceleration");
        this.releasePlayer();
        Toast.makeText(this, "Error with hardware acceleration", Toast.LENGTH_LONG).show();
    }
}

电视 Activity

public class tvActivity extends LeanbackActivity {

    DirectorAdaptor mAdapter;
    LibVLC mLibVLC = null;
    MediaPlayer mMediaPlayer = null;

    boolean mPlayingVideo = false; // Don't destroy libVLC if the video activity is playing.

    private void playMediaAtPath(String path) {
        // To play with LibVLC, we need a media player object.
        // Let's get one, if needed.
        if(mMediaPlayer == null)
            mMediaPlayer = new MediaPlayer(mLibVLC);

        // Create a new Media object for the file.
        // Each media - a song, video, or stream is represented by a Media object for LibVLC.
        Media m = new Media(mLibVLC, path);

        // Tell the media player to play the new Media.
        mMediaPlayer.setMedia(m);

        // Finally, play it!
        mMediaPlayer.play();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        try {
            mLibVLC = new LibVLC(this);
        } catch(IllegalStateException e) {
            Toast.makeText(tvActivity.this,
                    "Error initializing the libVLC multimedia framework!",
                    Toast.LENGTH_LONG).show();
            finish();
        }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_stream);

        Intent intent = new Intent(tvActivity.this, VideoActivity.class);
        //intent.putExtra(VideoActivity.LOCATION, "http://dl.strem.io/BigBuckBunny_512kb.mp4");
        intent.putExtra("stream", "http://129.205.0.34/twendesmart/tube/testIPTV/IPTVWorld.m3u");
        startActivity(intent);
    }
}

这是播放器的问题还是需要额外的库来解析 m3u 播放列表?

谢谢

最佳答案

要使用 libvlc 播放 m3u,您需要:

  1. 从您的 m3u 创建一个媒体(您已完成)。
  2. Media 上调用解析,如果 m3u 是远程流,则可能使用 ParseNetwork 选项。
  3. 解析完成后探索媒体中的子项目。
  4. 通过将其中一个子项目提供给媒体播放器来播放它。

祝你好运。

关于java - 使用 LibVLC 在 Android 应用程序上加载 m3u 播放列表失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55215379/

相关文章:

java - 旋转矩形中的碰撞检测

android - 如何使用 Intent 打开 youtube 应用程序

android - 需要有关 Android 声音处理的帮助/建议

java - Android:OnClickListener 在初始加载时无响应?

chromecast - 使用 Google Cast 转换到 Android TV 时,是否可以捕捉到 Android TV 的 Remote 按钮?

android - 收听 Intent 变化

java - 当 Activity 屏幕首次在 Android Studio 上加载时,如何在隐藏背景中发送带有当前位置数据的 SMS 文本消息?

java - 删除 JLayeredPane 中的图层

java - 在 Android 中以编程方式更改 DNS

java - 如何使用语句和循环实现密码规则?