mk_player.cpp 8.65 KB
Newer Older
1
/*
xiongziliang committed
2
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
3 4 5
 *
 * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
 *
xiongziliang committed
6 7 8
 * 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.
9 10
 */

11
#include "mk_player.h"
12 13 14 15 16 17
#include "Util/logger.h"
#include "Player/MediaPlayer.h"
using namespace std;
using namespace toolkit;
using namespace mediakit;

xiongziliang committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
class MediaPlayerForC : public std::enable_shared_from_this<MediaPlayerForC>{
public:
    typedef std::shared_ptr<MediaPlayerForC> Ptr;

    MediaPlayerForC(){
        _player = std::make_shared<MediaPlayer>();
    }
    ~MediaPlayerForC(){}

    MediaPlayer *operator->(){
        return _player.get();
    }

    void setup(){
        weak_ptr<MediaPlayerForC> weak_self = shared_from_this();
        _player->setOnPlayResult([weak_self](const SockException &ex){
            auto strong_self = weak_self.lock();
            if(strong_self){
                strong_self->onEvent(false,ex);
            }
        });

        _player->setOnShutdown([weak_self](const SockException &ex){
            auto strong_self = weak_self.lock();
            if(strong_self){
                strong_self->onEvent(true,ex);
            }
        });
    }

48 49 50 51 52 53 54
    void unset(){
        lock_guard<recursive_mutex> lck(_mtx);
        _on_play = nullptr;
        _on_shutdown = nullptr;
        _on_data = nullptr;
    }

xiongziliang committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
    void onEvent(bool is_shutdown, const SockException &ex){
        lock_guard<recursive_mutex> lck(_mtx);
        if(is_shutdown){
            //播放中断
            if(_on_shutdown){
                _on_shutdown(_on_shutdown_data,ex.getErrCode(),ex.what());
            }
            return;
        }

        //播放结果
        if(_on_play){
            _on_play(_on_play_data,ex.getErrCode(),ex.what());
        }

        if(ex){
            //播放失败
            return;
        }

        //播放成功,添加事件回调
        weak_ptr<MediaPlayerForC> weak_self = shared_from_this();
        auto delegate = std::make_shared<FrameWriterInterfaceHelper>([weak_self](const Frame::Ptr &frame) {
            auto strong_self = weak_self.lock();
            if (strong_self) {
                strong_self->onData(frame);
            }
        });
83
        for (auto &track : _player->getTracks(false)) {
xiongziliang committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
            track->addDelegate(delegate);
        }
    }

    void onData(const Frame::Ptr &frame){
        lock_guard<recursive_mutex> lck(_mtx);
        if(_on_data){
            _on_data(_on_data_data,frame->getTrackType(),frame->getCodecId(),frame->data(),frame->size(),frame->dts(),frame->pts());
        }
    }

    void setOnEvent(on_mk_play_event cb, void *user_data, int type) {
        lock_guard<recursive_mutex> lck(_mtx);
        if(type == 0){
            _on_play_data = user_data;
            _on_play = cb;
        }else{
            _on_shutdown_data = user_data;
            _on_shutdown = cb;
        }
    }

    void setOnData(on_mk_play_data cb, void *user_data) {
        lock_guard<recursive_mutex> lck(_mtx);
        _on_data_data = user_data;
        _on_data = cb;
    }

    MediaPlayer::Ptr& getPlayer(){
        return _player;
    }
private:
    MediaPlayer::Ptr _player;
    recursive_mutex _mtx;
    on_mk_play_event _on_play = nullptr;
    on_mk_play_data _on_data = nullptr;
    on_mk_play_event _on_shutdown = nullptr;

    void *_on_play_data = nullptr;
    void *_on_shutdown_data = nullptr;
    void *_on_data_data = nullptr;
};

127
API_EXPORT mk_player API_CALL mk_player_create() {
xiongziliang committed
128 129
    MediaPlayerForC::Ptr *obj = new MediaPlayerForC::Ptr(new MediaPlayerForC());
    (*obj)->setup();
130
    return obj;
131 132
}
API_EXPORT void API_CALL mk_player_release(mk_player ctx) {
133
    assert(ctx);
xiongziliang committed
134
    MediaPlayerForC::Ptr *obj = (MediaPlayerForC::Ptr *)ctx;
135
    (*obj)->unset();
136
    delete obj;
137 138 139
}

API_EXPORT void API_CALL mk_player_set_option(mk_player ctx,const char* key,const char *val){
140
    assert(ctx && key && val);
xiongziliang committed
141 142
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto player = obj.getPlayer();
143 144 145 146 147
    string key_str(key), val_str(val);
    player->getPoller()->async([key_str,val_str,player](){
        //切换线程后再操作
        (*player)[key_str] = val_str;
    });
148 149
}
API_EXPORT void API_CALL mk_player_play(mk_player ctx, const char *url) {
150
    assert(ctx && url);
xiongziliang committed
151 152
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto player = obj.getPlayer();
153 154 155 156 157
    string url_str(url);
    player->getPoller()->async([url_str,player](){
        //切换线程后再操作
        player->play(url_str);
    });
158 159 160
}

API_EXPORT void API_CALL mk_player_pause(mk_player ctx, int pause) {
161
    assert(ctx);
xiongziliang committed
162 163
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto player = obj.getPlayer();
164 165 166 167
    player->getPoller()->async([pause,player](){
        //切换线程后再操作
        player->pause(pause);
    });
168 169 170 171
}

API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress) {
    assert(ctx);
xiongziliang committed
172 173
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto player = obj.getPlayer();
174 175 176 177 178 179 180
    player->getPoller()->async([progress,player](){
        //切换线程后再操作
        player->seekTo(progress);
    });
}

static void mk_player_set_on_event(mk_player ctx, on_mk_play_event cb, void *user_data, int type) {
181
    assert(ctx);
xiongziliang committed
182 183
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    obj.setOnEvent(cb,user_data, type);
184 185 186
}

API_EXPORT void API_CALL mk_player_set_on_result(mk_player ctx, on_mk_play_event cb, void *user_data) {
187
    mk_player_set_on_event(ctx,cb,user_data,0);
188 189 190
}

API_EXPORT void API_CALL mk_player_set_on_shutdown(mk_player ctx, on_mk_play_event cb, void *user_data) {
191
    mk_player_set_on_event(ctx,cb,user_data,1);
192 193 194
}

API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb, void *user_data) {
195
    assert(ctx);
xiongziliang committed
196 197
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    obj.setOnData(cb,user_data);
198 199
}

xiongziliang committed
200
API_EXPORT int API_CALL mk_player_video_codecId(mk_player ctx){
201
    assert(ctx);
xiongziliang committed
202 203
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
204 205 206
    return track ? track->getCodecId() : CodecInvalid;
}

207
API_EXPORT int API_CALL mk_player_video_width(mk_player ctx) {
208
    assert(ctx);
xiongziliang committed
209 210
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
211
    return track ? track->getVideoWidth() : 0;
212 213 214
}

API_EXPORT int API_CALL mk_player_video_height(mk_player ctx) {
215
    assert(ctx);
xiongziliang committed
216 217
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
218
    return track ? track->getVideoHeight() : 0;
219 220 221
}

API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx) {
222
    assert(ctx);
xiongziliang committed
223 224
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
225
    return track ? track->getVideoFps() : 0;
226 227
}

xiongziliang committed
228
API_EXPORT int API_CALL mk_player_audio_codecId(mk_player ctx){
229
    assert(ctx);
xiongziliang committed
230 231
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio));
232 233 234
    return track ? track->getCodecId() : CodecInvalid;
}

235
API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx) {
236
    assert(ctx);
xiongziliang committed
237 238
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio));
239
    return track ? track->getAudioSampleRate() : 0;
240 241 242
}

API_EXPORT int API_CALL mk_player_audio_bit(mk_player ctx) {
243
    assert(ctx);
xiongziliang committed
244 245
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio));
246
    return track ? track->getAudioSampleBit() : 0;
247 248 249
}

API_EXPORT int API_CALL mk_player_audio_channel(mk_player ctx) {
250
    assert(ctx);
xiongziliang committed
251 252
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio));
253
    return track ? track->getAudioChannel() : 0;
254 255 256
}

API_EXPORT float API_CALL mk_player_duration(mk_player ctx) {
257
    assert(ctx);
xiongziliang committed
258 259
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    return obj->getDuration();
260 261 262
}

API_EXPORT float API_CALL mk_player_progress(mk_player ctx) {
263
    assert(ctx);
xiongziliang committed
264 265
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    return obj->getProgress();
266 267 268
}

API_EXPORT float API_CALL mk_player_loss_rate(mk_player ctx, int track_type) {
269
    assert(ctx);
xiongziliang committed
270 271
    MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
    return obj->getPacketLossRate((TrackType)track_type);
272
}