Jtt1078Handler.java 8.33 KB
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.genersoft.iot.vmp.jt1078.server;

import com.genersoft.iot.vmp.VManageBootstrap;
import com.genersoft.iot.vmp.conf.MediaConfig;
import com.genersoft.iot.vmp.jt1078.app.VideoServerApp;
import com.genersoft.iot.vmp.jt1078.publisher.Channel;
import com.genersoft.iot.vmp.jt1078.publisher.PublishManager;
import com.genersoft.iot.vmp.jt1078.util.Packet;
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
import com.genersoft.iot.vmp.service.IStreamProxyService;
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
import com.genersoft.iot.vmp.vmanager.jt1078.platform.config.Jt1078ConfigBean;
import com.genersoft.iot.vmp.vmanager.streamProxy.StreamProxyController;
import io.lettuce.core.support.caching.RedisCache;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

public class Jtt1078Handler extends SimpleChannelInboundHandler<Packet> {
    static Logger logger = LoggerFactory.getLogger(Jtt1078Handler.class);
    private static final AttributeKey<Session> SESSION_KEY = AttributeKey.valueOf("session-key");
    private ChannelHandlerContext context;
    private String tagMapping;
    private Integer httpPort;

    public Jtt1078Handler(String tagMapping, Integer httpPort) {
        this.tagMapping = tagMapping;
        this.httpPort = httpPort;
    }

    protected void channelRead0(ChannelHandlerContext ctx, Packet packet) throws Exception {
        this.context = ctx;
        packet.seek(8);
        String sim = packet.nextBCD() + packet.nextBCD() + packet.nextBCD() + packet.nextBCD() + packet.nextBCD() + packet.nextBCD();
        int channel = packet.nextByte() & 255;
        String tag = sim + "-" + channel;
        if (StringUtils.isEmpty(this.tagMapping)) {
            this.tagMapping = tag;
        }

        if (!StringUtils.endsWith(this.tagMapping, ".flv")) {
            endWithMapping(this.tagMapping);
        }


        Session session = this.getSession();
        if (null == session) {
            this.setSession(session = new Session());
            Channel chl = PublishManager.getInstance().open(this.tagMapping, this.httpPort);
            session.set("tag", this.tagMapping);
            logger.info("start publishing: {} -> {}-{}", new Object[]{Long.toHexString((long) chl.hashCode() & 4294967295L), sim, channel});
        }

        Integer sequence = (Integer) session.get("video-sequence");
        if (sequence == null) {
            sequence = 0;
        }

        int lengthOffset = 28;
        int dataType = packet.seek(15).nextByte() >> 4 & 15;
        int pkType = packet.seek(15).nextByte() & 15;
        if (dataType == 4) {
            lengthOffset = 16;
        } else if (dataType == 3) {
            lengthOffset = 24;
        }

        int pt = packet.seek(5).nextByte() & 127;
        long timestamp;
        if (dataType != 0 && dataType != 1 && dataType != 2) {
            if (dataType == 3) {
                timestamp = packet.seek(16).nextLong();
                byte[] data = packet.seek(lengthOffset + 2).nextBytes();
                PublishManager.getInstance().publishVideo(this.tagMapping, sequence, timestamp, pt, data);
            }
        } else {
            if (pkType == 0 || pkType == 2) {
                sequence = sequence + 1;
                session.set("video-sequence", sequence);
            }

            timestamp = packet.seek(16).nextLong();
            PublishManager.getInstance().publishVideo(this.tagMapping, sequence, timestamp, pt, packet.seek(lengthOffset + 2).nextBytes());
        }

    }

    private byte[] convert(String str) {
        byte[] bytes = str.getBytes();
        new StringBuilder();
        int length = bytes.length;
        byte[] bys = new byte[length];

        for (int i = 0; i < length; ++i) {
            bys[i] = Byte.valueOf(Integer.toBinaryString(bytes[i]) + "");
        }

        return bys;
    }

    public final Session getSession() {
        Attribute<Session> attr = this.context.channel().attr(SESSION_KEY);
        return null == attr ? null : (Session) attr.get();
    }

    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        this.release();
    }

    public final void setSession(Session session) {
        this.context.channel().attr(SESSION_KEY).set(session);
    }

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        this.release();
        ctx.close();
    }

    private void release() {
        String tag = (String) this.getSession().get("tag");
        if (tag != null) {
            logger.info("close netty channel: {}", tag);
            PublishManager.getInstance().close(tag);
        }

    }

    public static void createStreamProxy(String stream, Integer port) throws URISyntaxException, IOException {
        Jt1078ConfigBean jt1078ConfigBean = VManageBootstrap.getBean(Jt1078ConfigBean.class);
        MediaConfig mediaConfig = VManageBootstrap.getBean(MediaConfig.class);
        StreamProxyController streamProxyController = VManageBootstrap.getBean(StreamProxyController.class);

        if (StringUtils.endsWith(stream, ".flv")) {
            stream = StringUtils.substringBeforeLast(stream, ".flv");
        }
        if(Objects.isNull(jt1078ConfigBean)){
            return;
        }
        String url = StringUtils.replace(jt1078ConfigBean.getGetURL(), "{stream}", stream);
        url = StringUtils.replace(url, "{port}", port + "");
        if (!StringUtils.endsWith(url, ".flv")) {
            url = url + ".flv";
        }
        StreamProxyItem item = new StreamProxyItem();
        item.setApp("schedule");
        item.setEnable(true);
        item.setEnableAudio(true);
        item.setRtpType("default");
        item.setStream(stream);
        item.setMediaServerId(mediaConfig.getId());
        item.setUrl(url);
        item.setFfmpegCmdKey("ffmpeg.cmd");
        item.setEnable(true);
        item.setEnableAudio(true);
        item.setEnableMp4(false);
        item.setEnableRemoveNoneReader(false);
        item.setEnableDisableNoneReader(false);
        item.setName(stream);

        StringRedisTemplate redisTemplate = VManageBootstrap.getBean(StringRedisTemplate.class);
        String key = "jtt1078:" + stream;
        String closeKey = "jt1078:count:"+stream;
        String timeoutKey = "timeout:"+stream;
        Object timeOutVal = redisTemplate.opsForValue().get(timeoutKey);
        if(Objects.equals("2",timeOutVal)){
            IStreamProxyService streamProxyService = VManageBootstrap.getBean(IStreamProxyService.class);
            streamProxyService.stop1("schedule",stream);
            redisTemplate.delete(timeoutKey);
        }

        if(redisTemplate.hasKey(closeKey)){
            IStreamProxyService streamProxyService = VManageBootstrap.getBean(IStreamProxyService.class);
            streamProxyService.del("schedule",stream);
        }else  if (redisTemplate.hasKey(key)) {
            redisTemplate.opsForValue().set(key, "1", 300, TimeUnit.SECONDS);
        } else {
            try {
                streamProxyController.save(item);
            }catch (Exception e){
                logger.error(e.getMessage());
            }
            timeOutVal = redisTemplate.opsForValue().get(timeoutKey);
            if(Objects.equals("2",timeOutVal)) {
                IStreamProxyService streamProxyService = VManageBootstrap.getBean(IStreamProxyService.class);
                streamProxyService.stop1("schedule", stream);
                redisTemplate.delete(timeoutKey);
            }

        }
    }

    private synchronized String endWithMapping(String tagMapping) throws URISyntaxException, IOException {
        if (!StringUtils.endsWith(this.tagMapping, ".flv")) {
            this.tagMapping = this.tagMapping + ".flv";
        }
        return this.tagMapping;
    }
}