MediaSource.h 6.98 KB
Newer Older
1
/*
2 3
 * MIT License
 *
xiongziliang committed
4
 * Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
 *
 * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */


#ifndef ZLMEDIAKIT_MEDIASOURCE_H
#define ZLMEDIAKIT_MEDIASOURCE_H

#include <mutex>
#include <string>
#include <memory>
#include <functional>
#include <unordered_map>
#include "Common/config.h"
xiongziliang committed
37
#include "Common/Parser.h"
38 39 40
#include "Util/logger.h"
#include "Util/TimeTicker.h"
#include "Util/NoticeCenter.h"
xiongziliang committed
41
#include "Extension/Track.h"
42 43

using namespace std;
xiongziliang committed
44
using namespace toolkit;
45

46 47 48 49
namespace toolkit{
    class TcpSession;
}//namespace toolkit

xiongziliang committed
50
namespace mediakit {
51

52 53
class MediaSource;
class MediaSourceEvent{
54 55 56 57
public:
    MediaSourceEvent(){};
    virtual ~MediaSourceEvent(){};
public:
xiongziliang committed
58
    virtual bool seekTo(MediaSource &sender,uint32_t ui32Stamp){
59
        //拖动进度条
60 61
        return false;
    }
62

xiongziliang committed
63
    virtual bool close(MediaSource &sender,bool force) {
64 65 66
        //通知其停止推流
        return false;
    }
67

xiongziliang committed
68
    virtual void onNoneReader(MediaSource &sender);
69
};
70 71

class MediaInfo{
72 73 74 75 76 77 78 79 80 81
public:
    MediaInfo(){}
    MediaInfo(const string &url){
        parse(url);
    }
    ~MediaInfo(){}

    void parse(const string &url);

    string &operator[](const string &key){
82
        return _params[key];
83 84
    }
public:
85 86 87 88 89 90 91
    string _schema;
    string _host;
    string _port;
    string _vhost;
    string _app;
    string _streamid;
    StrCaseMap _params;
92
    string _param_strs;
93 94 95 96 97 98 99 100 101 102 103 104 105 106
};

class MediaSource: public enable_shared_from_this<MediaSource> {
public:
    typedef std::shared_ptr<MediaSource> Ptr;
    typedef unordered_map<string, weak_ptr<MediaSource> > StreamMap;
    typedef unordered_map<string, StreamMap > AppStreamMap;
    typedef unordered_map<string, AppStreamMap > VhostAppStreamMap;
    typedef unordered_map<string, VhostAppStreamMap > SchemaVhostAppStreamMap;

    MediaSource(const string &strSchema,
                const string &strVhost,
                const string &strApp,
                const string &strId) :
107 108 109
            _strSchema(strSchema),
            _strApp(strApp),
            _strId(strId) {
110
        if(strVhost.empty()){
111
            _strVhost = DEFAULT_VHOST;
112
        }else{
113
            _strVhost = strVhost;
114 115 116 117 118 119 120 121 122 123 124 125
        }
    }
    virtual ~MediaSource() {
        unregist();
    }

    static Ptr find(const string &schema,
                    const string &vhost,
                    const string &app,
                    const string &id,
                    bool bMake = true) ;

126 127 128 129 130
    static void findAsync(const MediaInfo &info,
                          const std::shared_ptr<TcpSession> &session,
                          bool retry,
                          const function<void(const MediaSource::Ptr &src)> &cb);

131
    const string& getSchema() const {
132
        return _strSchema;
133 134
    }
    const string& getVhost() const {
135
        return _strVhost;
136 137 138
    }
    const string& getApp() const {
        //获取该源的id
139
        return _strApp;
140 141
    }
    const string& getId() const {
142
        return _strId;
143 144 145
    }

    bool seekTo(uint32_t ui32Stamp) {
146
        auto listener = _listener.lock();
147 148 149
        if(!listener){
            return false;
        }
xiongziliang committed
150
        return listener->seekTo(*this,ui32Stamp);
151 152
    }

153 154
    virtual uint32_t getTimeStamp(TrackType trackType) = 0;

155
    bool close(bool force) {
156
        auto listener = _listener.lock();
157 158 159
        if(!listener){
            return false;
        }
xiongziliang committed
160
        return listener->close(*this,force);
161
    }
xiongziliang committed
162 163 164 165 166 167 168 169

    void onNoneReader(){
        auto listener = _listener.lock();
        if(!listener){
            return;
        }
        listener->onNoneReader(*this);
    }
170
    virtual void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
171
        _listener = listener;
172
    }
173 174 175 176 177 178 179 180 181 182 183 184 185 186

    template <typename FUN>
    static void for_each_media(FUN && fun){
        lock_guard<recursive_mutex> lock(g_mtxMediaSrc);
        for (auto &pr0 : g_mapMediaSrc){
            for(auto &pr1 : pr0.second){
                for(auto &pr2 : pr1.second){
                    for(auto &pr3 : pr2.second){
                        fun(pr0.first,pr1.first,pr2.first,pr3.first,pr3.second.lock());
                    }
                }
            }
        }
    }
187

188
    virtual int readerCount() = 0;
189
protected:
190
    void regist() ;
191
    bool unregist() ;
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
private:
        template <typename FUN>
        static bool searchMedia(const string &schema,
                                const string &vhost,
                                const string &app,
                                const string &id,
                                FUN &&fun){
        auto it0 = g_mapMediaSrc.find(schema);
        if (it0 == g_mapMediaSrc.end()) {
            //未找到协议
            return false;
        }
        auto it1 = it0->second.find(vhost);
        if(it1 == it0->second.end()){
            //未找到vhost
            return false;
        }
        auto it2 = it1->second.find(app);
        if(it2 == it1->second.end()){
            //未找到app
            return false;
        }
        auto it3 = it2->second.find(id);
        if(it3 == it2->second.end()){
            //未找到streamId
            return false;
        }
        return fun(it0,it1,it2,it3);
    }
    template <typename IT0,typename IT1,typename IT2>
    static void eraseIfEmpty(IT0 it0,IT1 it1,IT2 it2){
        if(it2->second.empty()){
            it1->second.erase(it2);
            if(it1->second.empty()){
                it0->second.erase(it1);
                if(it0->second.empty()){
                    g_mapMediaSrc.erase(it0);
                }
            }
        }
    };
233

234 235
    void unregisted();
protected:
236
    std::weak_ptr<MediaSourceEvent> _listener;
237
private:
238 239 240 241
    string _strSchema;//协议类型
    string _strVhost; //vhost
    string _strApp; //媒体app
    string _strId; //媒体id
242 243 244 245
    static SchemaVhostAppStreamMap g_mapMediaSrc; //静态的媒体源表
    static recursive_mutex g_mtxMediaSrc; //访问静态的媒体源表的互斥锁
};

xiongziliang committed
246
} /* namespace mediakit */
247 248 249


#endif //ZLMEDIAKIT_MEDIASOURCE_H