vitamio直播流编程(供学习)

编写测试的RTMP直播流过程

1、在Android Studio中引用Vitamio库的步骤如下:

1. 下载Vitamio bundle第三方库, https://github.com/yixia/VitamioBundle,官方需要授权才可用其中功能。(https://www.vitamio.org 

2. 解压并且在Android Studio上File->Import Module

3. 指定到VitamioBundle路径,选择vitamio文件夹 点击完成

4. 在build.gradle(Module: app)依赖部分添加依赖项目(‘:vitamio’)

5. 打开build.gradle (Module: vitamio) - 改变最小sdk版本为7,我的修改为9,如不报错就行,报错系统会提示,修改相应版本即可。

不要忘记在manifest.xml中添加internet权限:<uses-permission  android:name="android.permission.INTERNET"/>加在<application>之外

6. 完成!

 

1、主Activity界面xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fac0ca"
    android:orientation="horizontal"
    android:gravity="center_horizontal"
    >
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_marginTop="20dp"
    android:layout_marginRight="15dp">
    <Button
        android:id="@+id/cctv12"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:text="中央新闻台"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/cctv12g"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="中央新闻高清"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/cctv1"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="中央1台"
        android:onClick="onclick"/>

    <Button
        android:id="@+id/cctv4"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="中央4台"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/cctv5"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="中央5台"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/cctv5g"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="中央5台高清"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/cctv6"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="中央6台"
        android:onClick="onclick"
        />
</LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_marginTop="20dp"
        android:layout_marginRight="15dp">
    <Button
        android:id="@+id/cctv6g"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="中央6台高清"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/hntv"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="湖南卫视"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/hntvg"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="湖南卫视高清"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/hktv"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="香港卫视"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/jstvg"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="江苏卫视高清"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/zjtvg"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="浙江卫视高清"
        android:onClick="onclick"/>
    <Button
        android:id="@+id/bttvg"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:background="@drawable/button1"
        android:textColor="#fff"
        android:text="兵团卫视"
        android:onClick="onclick"/>
    </LinearLayout>
</LinearLayout>
效果图:(所需资源图自行设计)

2、启动Java代码(包名因环境不同而不同)

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import java.util.HashMap;
import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;
import static io.vov.vitamio.MediaPlayer.VIDEOQUALITY_HIGH;

public class MainActivity extends AppCompatActivity {
    private static final String TAG "MainActivity";
    private String path;
    //private HashMap<String, String> options;
    private VideoView mVideoView;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainlayout);
     
    }

    public void onclick(View view){
        button=(Button) view;
        Intent intent = new Intent();
        intent.setClass(this, mainVidoPlayer.class);


        if(button.getText().toString().equals("中央新闻台"))
           {
            intent.putExtra("path""直播流地址XXXXXXX");//需要自行加入直播流地址,以下类似。
               //System.out.println("传前结果:"+button.getText());
            }
        else if (button.getText().toString().equals("中央新闻高清"))
        {
            intent.putExtra("path","直播流地址XXXXXXX");
        }
        else if (button.getText().toString().equals("中央1台"))
        {
            intent.putExtra("path""直播流地址XXXXXXX"");
        }
        else if (button.getText().toString().equals("中央4台"))
        {
            intent.putExtra("path""直播流地址XXXXXXX"");
        }
        else if (button.getText().toString().equals("中央5台"))
        {
            intent.putExtra("path""直播流地址XXXXXXX"");
        }
        else if (button.getText().toString().equals("中央5台高清"))
        {
            intent.putExtra("path""直播流地址XXXXXXX"");
        }
        else if (button.getText().toString().equals("中央6台"))
        {
            intent.putExtra("path""直播流地址XXXXXXX"");
        }
        else if (button.getText().toString().equals("中央6台高清"))
        {
            intent.putExtra("path""直播流地址XXXXXXX");
        }
        else if (button.getText().toString().equals("湖南卫视"))
        {
            intent.putExtra("path""rtmp:直播流地址XXXXXXX"");
        }
        else if (button.getText().toString().equals("湖南卫视高清"))
        {
            intent.putExtra("path""h ");
        }
        else if (button.getText().toString().equals("香港卫视"))
        {
            intent.putExtra("path""直播流地址XXXXXXX"");
        }
        else if (button.getText().toString().equals("江苏卫视高清"))
        {
            intent.putExtra("path""直播流地址XXXXXXX"");
        }
        else if (button.getText().toString().equals("浙江卫视高清"))
        {
            intent.putExtra("path""直播流地址XXXXXXX"");
        }
        else if (button.getText().toString().equals("兵团卫视"))
        {
            intent.putExtra("path""直播流地址XXXXXXX"");
        }
        startActivity(intent);



    }

3、播放界面xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <io.vov.vitamio.widget.VideoView
        android:id="@+id/surface_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

    <LinearLayout
        android:id="@+id/video_loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center_vertical" >

        <ProgressBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/video_loading_perce"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="7.0dip"
            android:text="@string/video_layout_loading"
            android:textColor="#ffffff"
            android:textSize="20.0sp" />
    </LinearLayout>

    <FrameLayout
        android:id="@+id/operation_volume_brightness"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="#00000000"
        android:orientation="horizontal"
        android:padding="0dip"
        android:visibility="invisible" >

        <ImageView
            android:id="@+id/operation_bg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@drawable/video_volumn_bg" />

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:paddingBottom="25dip" >

            <ImageView
                android:id="@+id/operation_full"
                android:layout_width="94dip"
                android:layout_height="wrap_content"
                android:layout_gravity="left"
                android:src="@drawable/video_num_bg" />

            <ImageView
                android:id="@+id/operation_percent"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_gravity="left"
                android:scaleType="matrix"
                android:src="@drawable/video_num_front" />
        </FrameLayout>
    </FrameLayout>

</RelativeLayout>
4、播放java代码

import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.MediaPlayer.OnCompletionListener;
import io.vov.vitamio.MediaPlayer.OnInfoListener;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

@SuppressLint("HandlerLeak")
public class mainVidoPlayer extends Activity implements OnCompletionListener, OnInfoListener {

    private String mPath;
    private String mTitle;
    private VideoView mVideoView;
    private View mVolumeBrightnessLayout;
    private ImageView mOperationBg;
    private ImageView mOperationPercent;
    private AudioManager mAudioManager;
    /** 声音 */
    private int mMaxVolume;
    /** 当前声音 */
    private int mVolume = -1;
    /** 当前亮度 */
    private float mBrightness = -1f;
    /** 当前缩放模式 */
    //private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;
    private int mLayout = VideoView.VIDEO_LAYOUT_SCALE;
    private GestureDetector mGestureDetector;
    private MediaController mMediaController;
    private View mLoadingView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        if (!LibsChecker.checkVitamioLibs(this))
            return;

        // ~~~ 获取播放地址和标
        // ~~~ 绑定控件
        setContentView(R.layout.activity_main);
        mPath = getIntent().getStringExtra("path");
        mVideoView = (VideoView) findViewById(R.id.surface_view);
        mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);
        mOperationBg = (ImageView) findViewById(R.id.operation_bg);
        mOperationPercent = (ImageView) findViewById(R.id.operation_percent);
        mLoadingView = findViewById(R.id.video_loading);
        // ~~~ 绑定事件
        mVideoView.setOnCompletionListener(this);
        mVideoView.setOnInfoListener(this);

        // ~~~ 绑定数据
        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
/*
        if (mPath.startsWith("http:")){
            mVideoView.setVideoURI(Uri.parse(mPath));
        }
        else{
            mVideoView.setVideoPath( mPath);
        }*/
        mVideoView.setVideoPath(mPath);//修改1多
        //System.out.println("播放后地址:"+mPath);//测试
        //设置显示名称
        mMediaController = new MediaController(this);

        mMediaController.setFileName(mTitle);
        mVideoView.setMediaController(mMediaController);
        mVideoView.requestFocus();

        mGestureDetector = new GestureDetector(this, new MyGestureListener());
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        if(!mVideoView.isPlaying())//判断是否播放,没有播放就执行播放。
        {mVideoView.start();}
    }
    public void onStart()
    {   super.onStart();
        if (!mVideoView.isPlaying())
        mVideoView.start();
        

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mVideoView != null)
            mVideoView.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mVideoView != null)
            mVideoView.resume();
    }

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mGestureDetector.onTouchEvent(event))
            return true;

        // 处理手势结束
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_UP:
                endGesture();
                break;
        }

        return super.onTouchEvent(event);
    }

    /** 手势结束 */
    private void endGesture() {
        mVolume = -1;
        mBrightness = -1f;

        // 隐藏
        mDismissHandler.removeMessages(0);
        mDismissHandler.sendEmptyMessageDelayed(0, 500);
    }

    private class MyGestureListener extends SimpleOnGestureListener {

        /** 双击 */
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)
                mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;
            else
                mLayout++;
            if (mVideoView != null)
                mVideoView.setVideoLayout(mLayout, 0);
            return true;
        }

        /** 滑动 */
        @SuppressWarnings("deprecation")
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            float mOldX = e1.getX(), mOldY = e1.getY();
            int y = (int) e2.getRawY();
            Display disp = getWindowManager().getDefaultDisplay();
            int windowWidth = disp.getWidth();
            int windowHeight = disp.getHeight();

            if (mOldX > windowWidth * 4.0 / 5)// 右边滑动
                onVolumeSlide((mOldY - y) / windowHeight);
            else if (mOldX < windowWidth / 5.0)// 左边滑动
                onBrightnessSlide((mOldY - y) / windowHeight);

            return super.onScroll(e1, e2, distanceX, distanceY);
        }
    }

    /** 定时隐藏 */
    private Handler mDismissHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            mVolumeBrightnessLayout.setVisibility(View.GONE);
        }
    };

    /**
     * 滑动改变声音大小
     *
     * @param percent
     */
    private void onVolumeSlide(float percent) {
        if (mVolume == -1) {
            mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
            if (mVolume < 0)
                mVolume = 0;

            // 显示
            mOperationBg.setImageResource(R.drawable.video_volumn_bg);
            mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
        }

        int index = (int) (percent * mMaxVolume) + mVolume;
        if (index > mMaxVolume)
            index = mMaxVolume;
        else if (index < 0)
            index = 0;

        // 变更声音
        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);

        // 变更进度
        ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
        lp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume;
        mOperationPercent.setLayoutParams(lp);
    }

    /**
     * 滑动改变亮度
     *
     * @param percent
     */
    private void onBrightnessSlide(float percent) {
        if (mBrightness < 0) {
            mBrightness = getWindow().getAttributes().screenBrightness;
            if (mBrightness <= 0.00f)
                mBrightness = 0.50f;
            if (mBrightness < 0.01f)
                mBrightness = 0.01f;

            // 显示
            mOperationBg.setImageResource(R.drawable.video_brightness_bg);
            mVolumeBrightnessLayout.setVisibility(View.VISIBLE);
        }
        WindowManager.LayoutParams lpa = getWindow().getAttributes();
        lpa.screenBrightness = mBrightness + percent;
        if (lpa.screenBrightness > 1.0f)
            lpa.screenBrightness = 1.0f;
        else if (lpa.screenBrightness < 0.01f)
            lpa.screenBrightness = 0.01f;
        getWindow().setAttributes(lpa);

        ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();
        lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);
        mOperationPercent.setLayoutParams(lp);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        if (mVideoView != null)
            mVideoView.setVideoLayout(mLayout, 0);
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onCompletion(MediaPlayer player) {
        Log.e("test", "完成播放");
    }

    private void stopPlayer() {
        if (mVideoView != null)
            mVideoView.pause();
    }

    private void startPlayer() {
        if (mVideoView != null)
            mVideoView.start();
    }

    private boolean isPlaying() {
        return mVideoView != null && mVideoView.isPlaying();
    }

    /** 是否自动恢复播放,用于自动暂停,恢复播放 */
    private boolean needResume;

    @Override
    public boolean onInfo(MediaPlayer arg0, int arg1, int down_rate) {
        switch (arg1) {
            case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                //缓存,暂停播
                if (!isPlaying()) {
                    stopPlayer();
                    needResume = true;
                }else
                {
                    startPlayer();
                    needResume=true;
                }
                mLoadingView.setVisibility(View.VISIBLE);
                break;
            case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                //缓存完成,继续播
                if (needResume)
                    startPlayer();
                mLoadingView.setVisibility(View.GONE);
                break;
            case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:
                //显示 下载速度
                Log.e("test","download rate:" + down_rate);

                break;
        }
        return true;
    }
}

 

4、配置文件Manifest.xml中加入

<activity android:name="io.vov.vitamio.activity.InitActivity"></activity>

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一: 使用javacv来实现,最终也是用过ffmpeg来进行编码和推,javacv实现到可以直接接收摄像头的帧数据 需要自己实现的代码只是打开摄像头,写一个SurfaceView进行预览,然后实现PreviewCallback将摄像头每一帧的数据交给javacv即可 javacv地址:https://github.com/bytedeco/javacv demo地址:https://github.com/beautifulSoup/RtmpRecoder/tree/master 二: 使用Android自带的编码工具,可实现硬编码,这里有一个国内大神开源的封装很完善的的库yasea,第一种方法需要实现的Camera采集部分也一起封装好了,进行一些简单配置就可以实现编码推,并且yasea目前已经直接支持摄像头的热切换,和各种滤镜效果 yasea地址(内置demo):https://github.com/begeekmyfriend/yasea 服务器 媒体服务器我用的是srs,项目地址:https://github.com/ossrs/srs 关于srs的编译、配置、部署、在官方wiki中已经写的很详细了,并且srs同样是国内开发人员开源的项目,有全中文的文档,看起来很方便 这里有最基本的简单编译部署过程 Android直播实现(二)srs媒体服务器部署 播放器 android端的播放使用vitamio,还是国内的开源播放器,是不是感觉国内的前辈们越来越屌了^~^! vitamio支持几乎所有常见的的视频格式和媒体协议 vitamio地址(内置demo):https://github.com/yixia/VitamioBundle 这里使用的是yaesa库,先介绍一下直播实现的程:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值