From 026aa5e75c2dee16eaefe8376e66be1549802569 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Wed, 18 Dec 2019 11:45:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=92=AD=E6=94=BE=E5=99=A8?= =?UTF-8?q?=E7=9A=84C=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/include/httpdownloader.h | 4 +- api/include/mediakit.h | 1 + api/include/player.h | 175 ++++++++++++++++++++++++++++++++ api/source/httpdownloader.cpp | 4 +- api/source/player.cpp | 183 ++++++++++++++++++++++++++++++++++ 5 files changed, 362 insertions(+), 5 deletions(-) create mode 100755 api/include/player.h create mode 100755 api/source/player.cpp diff --git a/api/include/httpdownloader.h b/api/include/httpdownloader.h index 73e7a1dd..8aeaa3d3 100755 --- a/api/include/httpdownloader.h +++ b/api/include/httpdownloader.h @@ -41,7 +41,7 @@ typedef void *mk_http_downloader; * @param err_msg 错误提示 * @param file_path 文件保存路径 */ -typedef void(API_CALL *on_download_complete)(void *user_data, int code, const char *err_msg, const char *file_path); +typedef void(API_CALL *on_mk_download_complete)(void *user_data, int code, const char *err_msg, const char *file_path); /** * 创建http[s]下载器 @@ -63,7 +63,7 @@ API_EXPORT void API_CALL mk_http_downloader_release(mk_http_downloader ctx); * @param cb 回调函数 * @param user_data 用户数据指针 */ -API_EXPORT void API_CALL mk_http_downloader_start(mk_http_downloader ctx, const char *url, const char *file, on_download_complete cb, void *user_data); +API_EXPORT void API_CALL mk_http_downloader_start(mk_http_downloader ctx, const char *url, const char *file, on_mk_download_complete cb, void *user_data); #ifdef __cplusplus diff --git a/api/include/mediakit.h b/api/include/mediakit.h index d8956749..789e70b6 100755 --- a/api/include/mediakit.h +++ b/api/include/mediakit.h @@ -32,5 +32,6 @@ #include "media.h" #include "proxyplayer.h" #include "flvrecorder.h" +#include "player.h" #endif /* MK_API_H_ */ diff --git a/api/include/player.h b/api/include/player.h new file mode 100755 index 00000000..50181c26 --- /dev/null +++ b/api/include/player.h @@ -0,0 +1,175 @@ +/* + * MIT License + * + * Copyright (c) 2019 xiongziliang <771730766@qq.com> + * + * 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 MK_PLAYER_H_ +#define MK_PLAYER_H_ + +#include "common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* mk_player; + +/** + * 播放结果或播放中断事件的回调 + * @param user_data 用户数据指针 + * @param err_code 错误代码,0为成功 + * @param err_msg 错误提示 + */ +typedef void(API_CALL *on_mk_play_event)(void *user_data,int err_code,const char *err_msg); + +/** + * 收到音视频数据回调 + * @param user_data 用户数据指针 + * @param track_type 0:视频,1:音频 + * @param codec_id 0:H264,1:H265,2:AAC + * @param data 数据指针 + * @param len 数据长度 + * @param dts 解码时间戳,单位毫秒 + * @param pts 显示时间戳,单位毫秒 + */ +typedef void(API_CALL *on_mk_play_data)(void *user_data,int track_type,int codec_id,void *data,int len,uint32_t dts,uint32_t pts); + +/** + * 创建一个播放器,支持rtmp/rtsp + * @return 播放器指针 + */ +API_EXPORT mk_player API_CALL mk_player_create(); + +/** + * 销毁播放器 + * @param ctx 播放器指针 + */ +API_EXPORT void API_CALL mk_player_release(mk_player ctx); + +/** + * 设置播放器配置选项 + * @param ctx 播放器指针 + * @param key 配置项键,支持 net_adapter/rtp_type/rtsp_user/rtsp_pwd/protocol_timeout_ms/media_timeout_ms/beat_interval_ms/max_analysis_ms + * @param val 配置项值,如果是整形,需要转换成统一转换成string + */ +API_EXPORT void API_CALL mk_player_set_option(mk_player ctx, const char *key, const char *val); + +/** + * 开始播放url + * @param ctx 播放器指针 + * @param url rtsp/rtmp url + */ +API_EXPORT void API_CALL mk_player_play(mk_player ctx, const char *url); + +/** + * 暂停或恢复播放,仅对点播有用 + * @param ctx 播放器指针 + * @param pause 1:暂停播放,0:恢复播放 + */ +API_EXPORT void API_CALL mk_player_pause(mk_player ctx, int pause); + +/** + * 设置点播进度条 + * @param ctx 对象指针 + * @param progress 取值范围未 0.0~1.0 + */ +API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress); + +/** + * 设置播放器开启播放结果回调函数 + * @param ctx 播放器指针 + * @param cb 回调函数指针 + * @param user_data 用户数据指针 + */ +API_EXPORT void API_CALL mk_player_set_on_result(mk_player ctx, on_mk_play_event cb, void *user_data); + +/** + * 设置播放被异常中断的回调 + * @param ctx 播放器指针 + * @param cb 回调函数指针,不得为null + * @param user_data 用户数据指针 + */ +API_EXPORT void API_CALL mk_player_set_on_shutdown(mk_player ctx, on_mk_play_event cb, void *user_data); + +/** + * 设置音视频数据回调函数 + * @param ctx 播放器指针 + * @param cb 回调函数指针,不得为null + * @param user_data 用户数据指针 + */ +API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb, void *user_data); + +/** + * 获取视频宽度 + */ +API_EXPORT int API_CALL mk_player_video_width(mk_player ctx); + +/** + * 获取视频高度 + */ +API_EXPORT int API_CALL mk_player_video_height(mk_player ctx); + +/** + * 获取视频帧率 + */ +API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx); + +/** + * 获取音频采样率 + */ +API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx); + +/** + * 获取音频采样位数,一般为16 + */ +API_EXPORT int API_CALL mk_player_audio_bit(mk_player ctx); + +/** + * 获取音频通道数 + */ +API_EXPORT int API_CALL mk_player_audio_channel(mk_player ctx); + +/** + * 获取点播节目时长,如果是直播返回0,否则返回秒数 + */ +API_EXPORT float API_CALL mk_player_duration(mk_player ctx); + +/** + * 获取点播播放进度,取值范围未 0.0~1.0 + */ +API_EXPORT float API_CALL mk_player_progress(mk_player ctx); + +/** + * 获取丢包率,rtsp时有效 + * @param ctx 对象指针 + * @param track_type 0:视频,1:音频 + */ +API_EXPORT float API_CALL mk_player_loss_rate(mk_player ctx, int track_type); + + +#ifdef __cplusplus +} +#endif + +#endif /* MK_PLAYER_H_ */ diff --git a/api/source/httpdownloader.cpp b/api/source/httpdownloader.cpp index f7a381ae..7a7bbf5f 100755 --- a/api/source/httpdownloader.cpp +++ b/api/source/httpdownloader.cpp @@ -26,8 +26,6 @@ #include "httpdownloader.h" #include "Util/logger.h" -#include "Util/TimeTicker.h" -#include "Util/onceToken.h" #include "Http/HttpDownloader.h" using namespace std; using namespace toolkit; @@ -43,7 +41,7 @@ API_EXPORT void API_CALL mk_http_downloader_release(mk_http_downloader ctx) { delete obj; } -API_EXPORT void API_CALL mk_http_downloader_start(mk_http_downloader ctx, const char *url, const char *file, on_download_complete cb, void *user_data) { +API_EXPORT void API_CALL mk_http_downloader_start(mk_http_downloader ctx, const char *url, const char *file, on_mk_download_complete cb, void *user_data) { HttpDownloader::Ptr *obj = (HttpDownloader::Ptr *) ctx; (*obj)->setOnResult([cb, user_data](ErrCode code, const string &errMsg, const string &filePath) { if (cb) { diff --git a/api/source/player.cpp b/api/source/player.cpp new file mode 100755 index 00000000..6686e837 --- /dev/null +++ b/api/source/player.cpp @@ -0,0 +1,183 @@ +/* + * MIT License + * + * Copyright (c) 2019 xiongziliang <771730766@qq.com> + * + * 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. + */ + +#include "player.h" +#include "Util/logger.h" +#include "Player/MediaPlayer.h" +using namespace std; +using namespace toolkit; +using namespace mediakit; + +API_EXPORT mk_player API_CALL mk_player_create() { + MediaPlayer::Ptr *obj = new MediaPlayer::Ptr(new MediaPlayer()); + return obj; +} +API_EXPORT void API_CALL mk_player_release(mk_player ctx) { + assert(ctx); + MediaPlayer::Ptr *obj = (MediaPlayer::Ptr *)ctx; + delete obj; +} + +API_EXPORT void API_CALL mk_player_set_option(mk_player ctx,const char* key,const char *val){ + assert(ctx); + assert(key); + assert(val); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + string key_str(key), val_str(val); + player->getPoller()->async([key_str,val_str,player](){ + //切换线程后再操作 + (*player)[key_str] = val_str; + }); +} +API_EXPORT void API_CALL mk_player_play(mk_player ctx, const char *url) { + assert(ctx); + assert(url); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + string url_str(url); + player->getPoller()->async([url_str,player](){ + //切换线程后再操作 + player->play(url_str); + }); +} + +API_EXPORT void API_CALL mk_player_pause(mk_player ctx, int pause) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + player->getPoller()->async([pause,player](){ + //切换线程后再操作 + player->pause(pause); + }); +} + +API_EXPORT void API_CALL mk_player_seekto(mk_player ctx, float progress) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + 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) { + assert(ctx); + assert(cb); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + player->getPoller()->async([cb,user_data,type,player](){ + //切换线程后再操作 + if(type == 0){ + player->setOnPlayResult([cb,user_data](const SockException &ex){ + cb(user_data,ex.getErrCode(),ex.what()); + }); + }else{ + player->setOnShutdown([cb,user_data](const SockException &ex){ + cb(user_data,ex.getErrCode(),ex.what()); + }); + } + }); +} + +API_EXPORT void API_CALL mk_player_set_on_result(mk_player ctx, on_mk_play_event cb, void *user_data) { + mk_player_set_on_event(ctx,cb,user_data,0); +} + +API_EXPORT void API_CALL mk_player_set_on_shutdown(mk_player ctx, on_mk_play_event cb, void *user_data) { + mk_player_set_on_event(ctx,cb,user_data,1); +} + +API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb, void *user_data) { + assert(ctx); + assert(cb); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + player->getPoller()->async([player,cb,user_data](){ + //切换线程后再操作 + auto delegate = std::make_shared([cb,user_data](const Frame::Ptr &frame){ + cb(user_data,frame->getTrackType(),frame->getCodecId(),frame->data(),frame->size(),frame->dts(),frame->pts()); + }); + for(auto &track : player->getTracks()){ + track->addDelegate(delegate); + } + }); +} + +API_EXPORT int API_CALL mk_player_video_width(mk_player ctx) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + auto track = dynamic_pointer_cast(player->getTrack(TrackVideo)); + return track ? track->getVideoWidth() : 0; +} + +API_EXPORT int API_CALL mk_player_video_height(mk_player ctx) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + auto track = dynamic_pointer_cast(player->getTrack(TrackVideo)); + return track ? track->getVideoHeight() : 0; +} + +API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + auto track = dynamic_pointer_cast(player->getTrack(TrackVideo)); + return track ? track->getVideoFps() : 0; +} + +API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + auto track = dynamic_pointer_cast(player->getTrack(TrackAudio)); + return track ? track->getAudioSampleRate() : 0; +} + +API_EXPORT int API_CALL mk_player_audio_bit(mk_player ctx) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + auto track = dynamic_pointer_cast(player->getTrack(TrackAudio)); + return track ? track->getAudioSampleBit() : 0; +} + +API_EXPORT int API_CALL mk_player_audio_channel(mk_player ctx) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + auto track = dynamic_pointer_cast(player->getTrack(TrackAudio)); + return track ? track->getAudioChannel() : 0; +} + +API_EXPORT float API_CALL mk_player_duration(mk_player ctx) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + return player->getDuration(); +} + +API_EXPORT float API_CALL mk_player_progress(mk_player ctx) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + return player->getProgress(); +} + +API_EXPORT float API_CALL mk_player_loss_rate(mk_player ctx, int track_type) { + assert(ctx); + MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx); + return player->getPacketLossRate((TrackType)track_type); +}