RtmpDemuxer.cpp 4.33 KB
Newer Older
xiongziliang committed
1
/*
xiongziliang committed
2 3 4 5 6 7 8 9
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
 *
 * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
 *
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
 */
xzl committed
10

11
#include "RtmpDemuxer.h"
12
#include "Extension/Factory.h"
xzl committed
13

xiongziliang committed
14
namespace mediakit {
xzl committed
15

16 17
void RtmpDemuxer::loadMetaData(const AMFValue &val){
    try {
xiongziliang committed
18 19 20 21 22 23
        int audiosamplerate = 0;
        int audiochannels = 0;
        int audiosamplesize = 0;
        const AMFValue *audiocodecid = nullptr;
        const AMFValue *videocodecid = nullptr;

24 25 26 27 28
        val.object_for_each([&](const string &key, const AMFValue &val) {
            if (key == "duration") {
                _fDuration = val.as_number();
                return;
            }
xiongziliang committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

            if(key == "audiosamplerate"){
                audiosamplerate = val.as_integer();
                return;
            }

            if(key == "audiosamplesize"){
                audiosamplesize = val.as_integer();
                return;
            }

            if(key == "stereo"){
                audiochannels = val.as_boolean() ? 2 : 1;
                return;
            }

            if(key == "videocodecid"){
                //找到视频
                videocodecid = &val;
                return;
            }

            if(key == "audiocodecid"){
                //找到音频
                audiocodecid = &val;
                return;
            }
56
        });
xiongziliang committed
57 58 59 60 61 62 63 64 65 66

        if(videocodecid){
            //有视频
            makeVideoTrack(*videocodecid);
        }

        if(audiocodecid){
            //有音频
            makeAudioTrack(*audiocodecid, audiosamplerate, audiochannels, audiosamplesize);
        }
67 68 69 70 71
    }catch (std::exception &ex){
        WarnL << ex.what();
    }
}

72
bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
73
    switch (pkt->typeId) {
xiongziliang committed
74
        case MSG_VIDEO: {
75 76
            if(!_tryedGetVideoTrack){
                _tryedGetVideoTrack = true;
xiongziliang committed
77 78
                auto codec = AMFValue(pkt->getMediaType());
                makeVideoTrack(codec);
79
            }
80 81 82
            if(_videoRtmpDecoder){
                return _videoRtmpDecoder->inputRtmp(pkt, true);
            }
83 84 85 86
            return false;
        }

        case MSG_AUDIO: {
87 88
            if(!_tryedGetAudioTrack) {
                _tryedGetAudioTrack = true;
xiongziliang committed
89
                auto codec = AMFValue(pkt->getMediaType());
xiongziliang committed
90
                makeAudioTrack(codec, pkt->getAudioSampleRate(), pkt->getAudioChannel(), pkt->getAudioSampleBit());
91
            }
92 93 94 95
            if(_audioRtmpDecoder){
                _audioRtmpDecoder->inputRtmp(pkt, false);
                return false;
            }
96 97 98 99 100
            return false;
        }
        default:
            return false;
    }
xzl committed
101 102
}

xiongziliang committed
103 104
void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
    //生成Track对象
105
    _videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getVideoTrackByAmf(videoCodec));
xiongziliang committed
106 107
    if (_videoTrack) {
        //生成rtmpCodec对象以便解码rtmp
108
        _videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack);
xiongziliang committed
109 110
        if (_videoRtmpDecoder) {
            //设置rtmp解码器代理,生成的frame写入该Track
111
            _videoRtmpDecoder->addDelegate(_videoTrack);
112
            onAddTrack(_videoTrack);
xiongziliang committed
113
            _tryedGetVideoTrack = true;
xiongziliang committed
114 115 116 117 118
        } else {
            //找不到相应的rtmp解码器,该track无效
            _videoTrack.reset();
        }
    }
xzl committed
119 120
}

xiongziliang committed
121
void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec,int sample_rate, int channels, int sample_bit) {
xiongziliang committed
122
    //生成Track对象
xiongziliang committed
123
    _audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getAudioTrackByAmf(audioCodec, sample_rate, channels, sample_bit));
xiongziliang committed
124 125
    if (_audioTrack) {
        //生成rtmpCodec对象以便解码rtmp
126
        _audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack);
xiongziliang committed
127 128
        if (_audioRtmpDecoder) {
            //设置rtmp解码器代理,生成的frame写入该Track
129
            _audioRtmpDecoder->addDelegate(_audioTrack);
130
            onAddTrack(_audioTrack);
xiongziliang committed
131
            _tryedGetAudioTrack = true;
xiongziliang committed
132 133 134 135 136
        } else {
            //找不到相应的rtmp解码器,该track无效
            _audioTrack.reset();
        }
    }
xzl committed
137
}
xiongziliang committed
138

xzl committed
139

xiongziliang committed
140
} /* namespace mediakit */