package com.maniu.gamelive;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.AsyncTask;

import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author Lance
 * @date 2019/5/9
 */
public class ScreenLive implements Runnable {

    static {
        System.loadLibrary("native-lib");
    }
    //视频推流

    private String url;
    //录屏管理类
    private MediaProjectionManager mediaProjectionManager;
    private boolean isLiving;
    //并发库中的BlockingQueue是一个比较好玩的类，顾名思义，就是阻塞队列。
    //该类主要提供了两个方法put()和take()，前者将一个对象放到队列中，
    // 如果队列已经满了，就等待直到有空闲节点；
    // 后者从head取一个对象，如果没有对象，就等待直到有可取的对象。
    private LinkedBlockingQueue<RTMPPackage> queue = new LinkedBlockingQueue<>();

    //MediaProjection是一个5.0之后给开发者提供的新的截屏或者录屏的新手段。MediaProjection可以用来捕捉屏幕，
    // 而MediaProjectionManager可以从命名上面来看到，它是是用来管理MediaProjection的。
    private MediaProjection mediaProjection;


    public void startLive(Activity activity, String url) {
        this.url = url;
        // 投屏管理器
        this.mediaProjectionManager = (MediaProjectionManager) activity
                .getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        // 创建截屏请求intent
        Intent captureIntent = mediaProjectionManager.createScreenCaptureIntent();
        activity.startActivityForResult(captureIntent, 100);
    }

    public void stoptLive() {
        addPackage(RTMPPackage.EMPTY_PACKAGE);
        isLiving = false;
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // 用户授权
        if (requestCode == 100 && resultCode == Activity.RESULT_OK) {
            // 获得截屏器
            mediaProjection = mediaProjectionManager.getMediaProjection
                    (resultCode, data);
            LiveTaskManager.getInstance().execute(this);
        }
    }

    public void addPackage(RTMPPackage rtmpPackage) {
        if (!isLiving) {
            return;
        }
        queue.add(rtmpPackage);
    }

    //核心推流
    @Override
    public void run() {
        //1、连接服务器  斗鱼rtmp服务器
        if (!connect(url)) {
            return;
        }
        isLiving = true;
        VideoCodec videoCodec = new VideoCodec(this);
        //把采集到的录屏信息存起来
        videoCodec.startLive(mediaProjection);
        AudioCodec audioCodec = new AudioCodec(this);
        audioCodec.startLive();
        boolean isSend = true;
        while (isLiving && isSend) {
            RTMPPackage rtmpPackage = null;
            try {
                rtmpPackage = queue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (null == rtmpPackage) {
                break;
            }
            if (rtmpPackage.getBuffer() != null && rtmpPackage.getBuffer().length != 0) {
                isSend = sendData(rtmpPackage.getBuffer(), rtmpPackage.getBuffer()
                        .length, rtmpPackage
                        .getType(), rtmpPackage.getTms());
            }
        }
        isLiving = false;
        videoCodec.stopLive();
        audioCodec.stopLive();
        queue.clear();
        disConnect();
    }

    private native boolean connect(String url);

    private native void disConnect();

    private native boolean sendData(byte[] data, int len, int type, long tms);

}
