//
//  WWVideoReplayView.m
//  wanwayInternet
//made in zhongdao  Copyright © 2020 liuchao. All rights reserved.
//

#import "VideoPlayView.h"
#import "SRWebSocket.h"
#import "H264DecodeTool.h"
#import "g726.h"
#import "g711.h"
#import "PCMStreamPlayer.h"
#import "YFTimerManager.h"
#import "YFProgressHUD.h"

@interface VideoPlayView ()<SRWebSocketDelegate, H264DecodeFrameCallbackDelegate, NSStreamDelegate,YFTimerDelegate>

@property (nonatomic,strong) SRWebSocket *websocket;
@property (nonatomic,strong) NSMutableData *receivedVideoData;
@property (nonatomic,strong) H264DecodeTool *h264Decoder;
@property (nonatomic, strong) PCMStreamPlayer *pcmPlayer;
@property (nonatomic, assign,getter=isStopPlayBuffer) BOOL stopPlayBuffer;
@property (nonatomic, strong) UIButton *playBtn;
@property (nonatomic, strong) YFProgressHUD *hud;
@end

@implementation VideoPlayView {
    g726_state_t *m_state726;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor blackColor];

        //g726 to pcm
        m_state726 = (g726_state_t *)malloc(sizeof(g726_state_t));
        m_state726 = g726_init(m_state726, 8000*5);//2-16kBits 3-24kBits 4-32kBits 5-40kBits
        _receivedVideoData = [NSMutableData data];
        
        //操作按钮
        [self addSubview:self.playBtn];
                
        [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(endShow)]];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.playBtn.center = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);
}

- (void)dealloc {
    NSLog(@"***** video replay view dealloc");
    [self stopPlay];
    _pcmPlayer = nil;
    _playLayer = nil;
    [self.websocket close];
}


//全屏播放
- (void)repalyFullScreenBtnTouchAction:(UIButton *)btn {
    btn.selected = !btn.selected;
    if (self.repalyDelegate && [self.repalyDelegate respondsToSelector:@selector(viedoReplayView:fullScreenAction:)]) {
        [self.repalyDelegate viedoReplayView:self fullScreenAction:btn.isSelected];
    }
}

- (void)endShow {
    if (self.hud) {
        [YFProgressHUD hiddenProgressHUDforView:self];
        self.hud = nil;
    }

    self.playBtn.hidden = NO;
    [self stopPlay];

    self.isPlaying = NO;
}

- (void)stopPlay {

    [YFTimerManager deleteTimerDelegate:self forTimeInterval:5.0];

    if (_websocket != nil && _websocket.readyState == SR_OPEN) {
        [_websocket close];
        
    }
    if (_websocket != nil) {
        _websocket = nil;
    }

    if (self.pcmPlayer) { [self.pcmPlayer resetPlay]; }

    if (_playLayer) {
        [_playLayer resetRenderBuffer];
        [_playLayer cleanUpTextures];
        self.stopPlayBuffer = YES;
    }
    
    if (_receivedVideoData.length > 0) {
        [_receivedVideoData resetBytesInRange:NSMakeRange(0, self.receivedVideoData.length)];
        _receivedVideoData.length = 0;
    }
}

- (void)beginShow {
    [self replayBtnTouchWith:self.wsUrl];
}

- (void)replayBtnTouchWith:(NSString *)wsUrl {

        if ([wsUrl isKindOfClass:[NSString class]] && wsUrl.length > 0) {
            self.stopPlayBuffer = NO;
            self.playBtn.hidden = YES;
            [self videoShowWithUrl:wsUrl];
            self.isPlaying = YES;
        }

}

- (void)videoShowWithUrl:(NSString *)url {
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    _websocket = [[SRWebSocket alloc] initWithURLRequest:req];
    _websocket.delegate = self;

    if (self.pcmPlayer) {
        [self.pcmPlayer resetPlay];
    }

    [self.playLayer resetRenderBuffer];
    [_websocket open];
   self.hud = [YFProgressHUD showProgressHUDinView:self title:@"努力加载视频中!"];

}

//发送心跳包
-(void)toDoThingsWhenTimeCome:(NSTimeInterval)interval{

    if (interval == 5.0) {
        if (self.websocket != nil && self.websocket.readyState == SR_OPEN) {
            NSLog(@"********* websocket send state %ld", self.websocket.readyState);
            [self.websocket send:@"0"];
        }
    }

}

#pragma mark ================ SRWebSocketDelegate =======================
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {
    NSLog(@"收到数据了******* %ld  %@   %@",webSocket.readyState, [message class], message);

    if ([message isKindOfClass:[NSData class]] == NO) { return; }

    NSData *data = [NSData dataWithData:message];
//    NSString *aString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//    NSLog(@"\n\n%@\n\n",aString)


    if (data.length < 24) { return; }
    //NSLog(@" --- begin --- %@", data);

    if (self.hud) {
        [YFProgressHUD hiddenProgressHUDforView:self];
        self.hud = nil;
    }

    //sim 卡号在收到的包头里。对讲用到
//    self.speakSimCardData = [data subdataWithRange:NSMakeRange(8, 6)];

    __weak typeof(self) weakself = self;
//    g726_state_t *weak_m_state726 = m_state726;

        NSInteger dataLength = data.length;
        NSInteger dataOffset = 0;

        while (dataOffset < dataLength) {

            //跳过5个字节没用
            NSData *typeData = [data subdataWithRange:NSMakeRange(dataOffset + 5, 1)]; //62 -> 0110 0010 -> 第1位，和后7位
            const Byte *byteData = (Byte *)[typeData bytes];

            Byte ptByte = byteData[0];
            int isComplete = ptByte >> 7;  //标志位，是否是完整数据帧边界，根据这个来拼接
            int loadType = ptByte & 0x7f;  //98位视频数据，否则为音频数据

            NSLog(@"%@ -- %d  %d", typeData, isComplete, loadType);

            if (loadType == 98) {
                NSData *videoSizeData = [data subdataWithRange:NSMakeRange(dataOffset + 28, 2)];
                const Byte *sizeBytes = (Byte *)[videoSizeData bytes];
                int size = (sizeBytes[0] & 0xff) * 16 * 16 +  (sizeBytes[1] & 0xff);
                NSData *videoPerData = [data subdataWithRange:NSMakeRange(dataOffset + 30, size)];

                //NSLog(@"---- one data %@", videoPerData);
                [weakself.receivedVideoData appendData:videoPerData]; //61 0110 0001
                
                dataOffset += 30 + size;
                
                //NSLog(@"size -- %@  %d %ld ",videoSizeData, size, dataOffset);
                if (isComplete > 0) {
                    //NSLog(@"---- all data %@", self.receivedVideoData);
                    [weakself.h264Decoder decodeNalu:(uint8_t *)[weakself.receivedVideoData bytes] size:(uint32_t)weakself.receivedVideoData.length alive:NO];
                    [weakself.receivedVideoData resetBytesInRange:NSMakeRange(0, weakself.receivedVideoData.length)];
                    weakself.receivedVideoData.length = 0;
                }
                
            } else {

                NSData *audioSizeData = [data subdataWithRange:NSMakeRange(dataOffset + 24, 2)];
                const Byte *sizeBytes = (Byte *)[audioSizeData bytes];
                int size = (sizeBytes[0] & 0xff) * 16 * 16 +  (sizeBytes[1] & 0xff);//[self intFromData:videoSizeData];
                NSData *audioData = [data subdataWithRange:NSMakeRange(dataOffset + 26, size)];
                NSLog(@"---- audio = %d  %ld-%d", loadType, dataLength,size);
                dataOffset += 26 + size;
                 //[self.fileHandle writeData:audioData];

                //G726  40k码率  8000采样频率  5bit采样位数
                //86 -- 1000 0110 -- loadType=6-G711A  8-G726

                //G726 转码 pcm
                //ffplay -f s16le -ac 1 -ar 8000  a.pcm
                //ffplay -f g726le -ar 8000 -ac 1 -code_size 5 -i test.g726
                int outLen = size*6, iRet = 0;
                short *outBuffer = (short *)malloc(outLen);
                unsigned char *audioDataBuffer = (unsigned char *)audioData.bytes;

                if (loadType == 6) {
                    // audio = 6  186-160
                    //iRet = 0, out = 320, {length = 320, bytes = 0x008a008e 00a600d9 ... 0801002d 005a007a }
                    outLen = g711_decode(outBuffer, &outLen, audioDataBuffer, size, TP_ALAW);
                } else if (loadType == 7) {
                    outLen = g711_decode(outBuffer, &outLen, audioDataBuffer, size, TP_ULAW);
                } else {
                    //audio = 8  126-100
                    //iRet = 160, out = 320, {length = 320, bytes = 0x0000fcff 1c00f4ff ... 4816c457 0c12a8da }
                    iRet = g726_decode(self->m_state726, outBuffer, audioDataBuffer, size);
                    outLen = iRet*2;
                }

                //不播放声音
                if (weakself.pcmPlayer) {
                    [weakself.pcmPlayer playWithData:(Byte *)outBuffer size:outLen];
                }
                free(outBuffer);
            }
        }

    //NSLog(@" --- end --- ");
}

- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
    [YFTimerManager addTimerDelegate:self forTimeInterval:5.0];
}

- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {
    if (self.hud) {
        [YFProgressHUD hiddenProgressHUDforView:self];
        self.hud = nil;
    }
    [YFTimerManager deleteTimerDelegate:self forTimeInterval:5.0];
    NSLog(@"*********** websocket error %@", error);
    [YFProgressHUD showToastTitle:(@"视频播放失败,请重试!")];
    [self endShow];

}

#pragma mark ================ H264DecodeFrameCallbackDelegate =======================
- (void)gotDecodedFrame:(CVImageBufferRef)imageBuffer {
    if(imageBuffer) {
        //解码回来的数据绘制播放
        if (!self.isStopPlayBuffer) {
            self.playLayer.pixelBuffer = imageBuffer;
            CVPixelBufferRelease(imageBuffer);
        }
    }
}

#pragma mark - getter

- (AAPLEAGLLayer *)playLayer {
    if (_playLayer == nil) {
        _playLayer = [[AAPLEAGLLayer alloc] initWithFrame:self.bounds];
        [self.layer insertSublayer:_playLayer atIndex:0];
    }
    return _playLayer;;
}


- (H264DecodeTool *)h264Decoder {
    if (_h264Decoder == nil) {
        _h264Decoder = [[H264DecodeTool alloc] init];
        _h264Decoder.delegate = self;
    }
    return _h264Decoder;
}

- (PCMStreamPlayer *)pcmPlayer {
    return nil;
}

- (UIButton *)playBtn{
    if (!_playBtn) {
        _playBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
        _playBtn.center = self.center;
        [_playBtn setImage:[UIImage imageNamed:@"ww_video_paly"] forState:UIControlStateNormal];
        [_playBtn addTarget:self action:@selector(beginShow) forControlEvents:UIControlEventTouchUpInside];
    }
    return _playBtn;
}

@end

