专属空间十一 ——私人影院(在线看电视台的直播)

  今天做的是一个看电视台直播的功能。

  MainActivity的布局是listView,直播布局页面写的是videoview中嵌套上下的一个panel和加载的一个动画。

  上面的显示的是卫视名称和当前的时间。

  需要注意的是直播源,也就是播放的卫视的网址链接,需要去在网上找或者是自己去抓取,网上找的话推荐去

  http://www.hdpfans.com这个网站去找,也给大家推荐一个我自己用的:https://ys.xitaofan.com/zbtv/zb.txt

 

 

 

 

 点击HDP直播,然后找上图这种的点开就会有网址链接,但是不一定有效。需要自己去测试。

  这样的话就需要你去下载一个VLC软件,打开后点击File-network,利用网络串流输入你找的这个网址链接测试是否有效。有效的话他就会播放电视台的直播。也就意味着你可用在你的代码中。

  这个软件还用了vitamio框架,可以去github上下载:https://github.com/yixia/VitamioBundle

  1、在你的项目建立一个model下的android library,或者直接而将vitamio导入你的android项目-File->new->Import Module,导入vitmio文件夹。注意的是导入之后vitamio目录下的build.gradle中配置,要和app目录下的build.gradle中的配置相同:

  2、在你的app的build下dependence中加入依赖implementation project(':vitamoi')

  3、需要在AndroidManifest中加入权限

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

  4、需要在Application中vitamio初始化Activity,和下图面一样。

    <activity
    android:name="io.vov.vitamio.activity.InitActivity"
    android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
    android:launchMode="singleTop"
    android:theme="@android:style/Theme.NoTitleBar"
    android:windowSoftInputMode="stateAlwaysHidden" />

  

  

 

 

   切记:我们代码中的videoview和Mediaplayer用的都是vitamio中的。hander用的是原生自带的android.os.   。

  完成效果图:

 

 

 

 

 

 

 

java:

package com.example.tvshow;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {
    private ListView mListView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = (ListView) findViewById(R.id.live_program);
        mListView.setAdapter(new ItemProgramAdapter(MainActivity.this));
    }
}
package com.example.tvshow;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ItemProgramAdapter extends BaseAdapter {
    private Context mContext;//数据集

    private String[] mDataList = new String[]{
            "凤凰卫视","广西卫视","陕西卫视","厦门卫视","韩国阿里郎","香港电影","湖南卫视",
            "广东卫视","黑龙江卫视"
    };
    private String[] mUrlList = new String[]{
            "http://117.169.72.6:8080/ysten-businessmobile/live/fhchinese/1.m3u8",
            "http://112.50.243.8/PLTV/88888888/224/3221225836/1.m3u8",
            "http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221225896/1.m3u8",
            "http://ott.fj.chinamobile.com/PLTV/88888888/224/3221226781/1.m3u8",
            "http://amdlive.ctnd.com.edgesuite.net/arirang_1ch/smil:arirang_1ch.smil/playlist.m3u8",
            "rtmp://58.200.131.2:1935/livetv/fhdy",
            "http://223.110.243.173/PLTV/3/224/3221227220/index.m3u8",
            "http://223.110.243.136/PLTV/3/224/3221227249/index.m3u8",
            "http://111.13.111.242/otttv.bj.chinamobile.com/PLTV/88888888/224/3221226239/1.m3u8"



    };
    @Override
    public int getCount() {
        return mDataList.length;
    }
    public ItemProgramAdapter(Context context){
        mContext = context;
    }
    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertview, ViewGroup viewGroup) {
        ViewHolder holder;
        if(convertview == null){
            convertview = LayoutInflater.from(mContext).inflate(R.layout.item_program_adapter,null);
            holder = new ViewHolder(convertview);
            convertview.setTag(holder);
        }else{
            holder = (ViewHolder) convertview.getTag();
        }
        holder.textView.setText(mDataList[position]);
        holder.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(mContext,LiveActivity.class);
                intent.putExtra("url",mUrlList[position]);
                intent.putExtra("title",mDataList[position]);
                mContext.startActivity(intent);
            }
        });
        return convertview;
    }

    private class ViewHolder {
        TextView textView;
        public ViewHolder(View view){
            textView = (TextView)view.findViewById(R.id.tv_item_program_title);
        }
    }
}
package com.example.tvshow;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.Vitamio;
import io.vov.vitamio.widget.VideoView;

public class LiveActivity extends AppCompatActivity {

    private static final String TAG = LiveActivity.class.getSimpleName();
    private String mUrl;
    private String mTitle;
    private ImageView mBackButton;
    private TextView mTextView;
    private TextView mSysTime;
    private io.vov.vitamio.widget.VideoView mVideoView;
    private static final int RETRY_TIMES = 5;
    private static final int AUTO_HIDE_TIME = 5000;
    private int mCount;
    private RelativeLayout mLoadingLayout;
    private Uri mUri;
    private RelativeLayout mRootView;
    private LinearLayout mTopLayout;
    private LinearLayout mBottomLayout;
    private Handler mHandler = new Handler(Looper.getMainLooper());
    private ImageView mPlayButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_live);
        mUrl = getIntent().getStringExtra("url");
        mTitle = getIntent().getStringExtra("title");
        Log.d(TAG,">> onCreate mTitle=" + mTitle + ", mUrl=" +mUrl);
        initView();
        initPlayer();
    }


    private void initPlayer() {
        Vitamio.isInitialized(getApplicationContext());
        Vitamio.initialize(this);
        //设置视频解码监听
        if (!LibsChecker.checkVitamioLibs(this)) {
            return;
        }
        mUri = Uri.parse(mUrl);
        mPlayButton = (ImageView) findViewById(R.id.iv_play);//播放按钮
        mPlayButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mVideoView.isPlaying()){
                    mVideoView.stopPlayback();
                    mPlayButton.setImageResource(R.drawable.pause_button_normal);
                }else {
                    mVideoView.setVideoURI(mUri);
                    mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            mVideoView.start();
                        }
                    });
                    mPlayButton.setImageResource(R.drawable.play_button_normal);
                }
            }
        });

        mVideoView = (VideoView) findViewById(R.id.surface_view);//播放界面

        mVideoView.setVideoURI(mUri);//解析地址
        /*new AlertDialog.Builder(LiveActivity.this)
                .setMessage("hello")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        ;
                    }
                }).setCancelable(false).show();
        */
        mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {

                mVideoView.start();
            }
        });

        /*MediaController controller = new MediaController(this);
        mVideoView.setMediaController(controller);*/
        mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                if(mCount > RETRY_TIMES){
                    new AlertDialog.Builder(LiveActivity.this)
                            .setMessage(R.string.err_message)
                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    LiveActivity.this.finish();
                                }
                            }).setCancelable(false).show();
                }else{
                    mVideoView.stopPlayback();
                    mVideoView.setVideoURI(Uri.parse(mUrl));
                }
                mCount++;
                return false;
            }
        });
        mVideoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
            @Override
            public boolean onInfo(MediaPlayer mediaPlayer, int i, int i1) {
                switch (i){
                    case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                        mLoadingLayout.setVisibility(View.VISIBLE);
                        break;
                    case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                        //音频先于视频出来
                    case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
                        //边下边播
                    case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
                        mLoadingLayout.setVisibility(View.GONE);
                        break;
                }
                return false;
            }
        });

    }

    private void initView() {
        mBackButton = (ImageView) findViewById(R.id.iv_back);
        mBackButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
        mTextView = (TextView) findViewById(R.id.tv_title);
        mTextView.setText(mTitle);
        mSysTime = (TextView)findViewById(R.id.tv_systime);
        mSysTime.setText(getCurrentTime());
        mLoadingLayout = (RelativeLayout) findViewById(R.id.rl_loading_layout);
        mRootView = (RelativeLayout) findViewById(R.id.activity_live);
        mTopLayout = (LinearLayout) findViewById(R.id.ll_top_layout);
        mBottomLayout = (LinearLayout) findViewById(R.id.ll_play_layout);

        mRootView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mBottomLayout.getVisibility() == View.VISIBLE
                        || mTopLayout.getVisibility() == View.VISIBLE){
                    mTopLayout.setVisibility(View.GONE);
                    mBottomLayout.setVisibility(View.GONE);
                    return;
                }

                if(mVideoView.isPlaying()){
                    //正在播放
                    mPlayButton.setImageResource(R.drawable.play_button_normal);
                }else{
                    mPlayButton.setImageResource(R.drawable.pause_button_normal);
                }
                mTopLayout.setVisibility(View.VISIBLE);
                mBottomLayout.setVisibility(View.VISIBLE);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mTopLayout.setVisibility(View.GONE);
                        mBottomLayout.setVisibility(View.GONE);
                    }
                },AUTO_HIDE_TIME);
            }
        });
    }
    private String getCurrentTime(){
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = sdf.format(c.getTime());
        return time;
    }

    @Override
    protected void onStop(){
        super.onStop();
        mCount = 0;
        if(mVideoView != null){
            mVideoView.stopPlayback();
        }
    }
}

Drawable中的vedio_loading.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="1080.0">
    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thicknessRatio="10"
        android:useLevel="false">
        <gradient
            android:centerColor="#FFDC35"
            android:centerY="0.50"
            android:endColor="#CE0000"
            android:startColor="#FFFFFF"
            android:type="sweep"
            android:useLevel="false"
            />
    </shape>

</rotate>

layout中的:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.tvshow.MainActivity">

    <ListView
        android:id="@+id/live_program"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv_item_program_title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:textSize="24sp"
        android:gravity="center"
        android:text="CCTV"/>

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/activity_live"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.tvshow.LiveActivity">

    <io.vov.vitamio.widget.VideoView
        android:id="@+id/surface_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <!--TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="666"
            android:textSize="50sp"
            android:textColor="@color/white"
            android:layout_centerHorizontal="true"
            android:layout_alignParentLeft="true"/-->

    <!--顶部panel-->
    <RelativeLayout
        android:id="@+id/rl_loading_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/rl_lodaing_bg">

        <ProgressBar
            android:id="@+id/pd_loading"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_centerInParent="true"
            android:indeterminate="false"
            android:indeterminateDrawable="@drawable/vedio_loading" />

        <TextView
            android:id="@+id/tv_loading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/pd_loading"
            android:layout_centerHorizontal="true"
            android:text="@string/loading"
            android:textColor="@color/White"
            android:textSize="24sp" />


    </RelativeLayout>
    <LinearLayout
        android:id="@+id/ll_top_layout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@color/player_panel_bg"
        android:layout_alignParentTop="true"
        android:visibility="gone"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/iv_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/return_button_normal"
            android:layout_gravity="center_vertical"
            android:paddingRight="5dp"/>
        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/White"
            android:textSize="20sp"
            android:text="@string/item_title_default"
            android:layout_gravity="center_vertical"/>
        <TextView
            android:id="@+id/tv_systime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/sys_time"
            android:textColor="@color/White"
            android:textSize="20sp"
            android:layout_marginLeft="190dp"
            android:layout_gravity="center_vertical"/>

    </LinearLayout>
    <!--底部panel-->
    <LinearLayout
        android:id="@+id/ll_play_layout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@color/player_panel_bg"
        android:layout_alignParentBottom="true"
        android:visibility="gone"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/iv_play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/play_button_normal"
            android:layout_gravity="center_vertical"
            android:paddingLeft="10dp"
            android:paddingRight="15dp"/>


    </LinearLayout>

</RelativeLayout>

 

可参考https://github.com/Realding/LiveApp

 

 

 

  

  

  

 

 

 

 

posted on 2020-08-14 01:44  沫戏回首  阅读(6388)  评论(0编辑  收藏  举报

导航