ZLMediaKit/src/Http/HlsPlayer.h

158 lines
4.4 KiB
C++
Raw Normal View History

/*
2020-05-17 18:00:37 +08:00
* Copyright (c) 2020 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
2020-05-17 18:00:37 +08:00
*
* 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.
*/
#ifndef HTTP_HLSPLAYER_H
#define HTTP_HLSPLAYER_H
#include <unordered_set>
#include "Util/util.h"
#include "Poller/Timer.h"
#include "Http/HttpDownloader.h"
#include "Player/MediaPlayer.h"
#include "HlsParser.h"
#include "HttpTSPlayer.h"
#include "Rtp/Decoder.h"
#include "Rtp/TSDecoder.h"
using namespace toolkit;
namespace mediakit {
class HlsPlayer : public HttpClientImp , public PlayerBase , public HlsParser{
public:
HlsPlayer(const EventPoller::Ptr &poller);
~HlsPlayer() override;
/**
*
* @param strUrl
*/
void play(const string &strUrl) override;
/**
*
*/
void teardown() override;
protected:
/**
* ts包
* @param data ts数据负载
* @param len ts包长度
*/
virtual void onPacket(const char *data, size_t len) = 0;
2020-05-17 18:00:37 +08:00
private:
/**
* m3u8成功
* @param is_m3u8_inner m3u8列表
* @param sequence ts列表seq
* @param ts_map ts列表或m3u8列表
*/
void onParsed(bool is_m3u8_inner,int64_t sequence,const map<int,ts_segment> &ts_map) override;
/**
* http回复头
* @param status :200 OK
* @param headers http头
* @return content的长度-1:content>=0:content
* http头中带有Content-Length字段时
*/
2021-01-19 16:05:38 +08:00
ssize_t onResponseHeader(const string &status,const HttpHeader &headers) override;
2020-05-17 18:00:37 +08:00
/**
* http conten数据
* @param buf
* @param size
* @param recvedSize (),totalSize时将触发onResponseCompleted回调
* @param totalSize
*/
2021-01-19 16:05:38 +08:00
void onResponseBody(const char *buf,size_t size,size_t recvedSize, size_t totalSize) override;
2020-05-17 18:00:37 +08:00
/**
* http回复完毕,
*/
void onResponseCompleted() override;
/**
* http链接断开回调
* @param ex
*/
void onDisconnect(const SockException &ex) override;
/**
*
* @param url url
* @param temporary
* @return
*/
bool onRedirectUrl(const string &url,bool temporary) override;
private:
void playDelay();
float delaySecond();
void playNextTs(bool force = false);
void teardown_l(const SockException &ex);
void play_l();
void onPacket_l(const char *data, size_t len);
2020-05-17 18:00:37 +08:00
private:
struct UrlComp {
//url忽略后面的参数
bool operator()(const string& __x, const string& __y) const {
return split(__x,"?")[0] < split(__y,"?")[0];
}
};
private:
bool _is_m3u8 = false;
bool _first = true;
int64_t _last_sequence = -1;
string _m3u8;
Timer::Ptr _timer;
Timer::Ptr _timer_ts;
list<ts_segment> _ts_list;
list<string> _ts_url_sort;
list<string> _m3u8_list;
set<string, UrlComp> _ts_url_cache;
HttpTSPlayer::Ptr _http_ts_player;
TSSegment _segment;
};
class HlsPlayerImp : public PlayerImp<HlsPlayer, PlayerBase> , public MediaSink{
public:
typedef std::shared_ptr<HlsPlayerImp> Ptr;
HlsPlayerImp(const EventPoller::Ptr &poller = nullptr);
~HlsPlayerImp() override {};
void setOnPacket(const TSSegment::onSegment &cb);
private:
void onPacket(const char *data, size_t len) override;
2020-05-17 18:00:37 +08:00
void onAllTrackReady() override;
void onPlayResult(const SockException &ex) override;
vector<Track::Ptr> getTracks(bool trackReady = true) const override;
bool inputFrame(const Frame::Ptr &frame) override;
2020-05-26 23:19:13 +08:00
void onShutdown(const SockException &ex) override;
void onTick();
2020-09-06 17:56:45 +08:00
int64_t getPlayPosition();
void setPlayPosition(int64_t pos);
int64_t getBufferMS();
2020-05-17 18:00:37 +08:00
private:
2020-09-06 17:56:45 +08:00
int64_t _ticker_offset = 0;
2020-05-26 23:19:13 +08:00
Ticker _ticker;
Stamp _stamp[2];
2020-09-06 17:56:45 +08:00
Timer::Ptr _timer;
DecoderImp::Ptr _decoder;
TSSegment::onSegment _on_ts;
multimap<int64_t, Frame::Ptr> _frame_cache;
2020-05-17 18:00:37 +08:00
};
}//namespace mediakit
#endif //HTTP_HLSPLAYER_H