Skip to content

Commit

Permalink
播放器新增支持音频:ZLMediaKit#945
Browse files Browse the repository at this point in the history
  • Loading branch information
xia-chu committed Jun 29, 2021
1 parent 66f28f5 commit 1b674a6
Show file tree
Hide file tree
Showing 128 changed files with 1,032 additions and 63,695 deletions.
8 changes: 4 additions & 4 deletions Android/app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ if(ENABLE_HLS)
aux_source_directory(${MediaServer_Root}/libmpeg/source src_mpeg)
include_directories(${MediaServer_Root}/libmpeg/include)
add_library(mpeg STATIC ${src_mpeg})
if(WIN32)
if(MSVC)
set_target_properties(mpeg PROPERTIES COMPILE_FLAGS ${VS_FALGS} )
endif(WIN32)
endif()
endif()

if(ENABLE_MP4)
Expand All @@ -85,9 +85,9 @@ if(ENABLE_MP4)
include_directories(${MediaServer_Root}/libflv/include)
add_library(mov STATIC ${src_mov})
add_library(flv STATIC ${src_flv})
if(WIN32)
if(MSVC)
set_target_properties(mov flv PROPERTIES COMPILE_FLAGS ${VS_FALGS} )
endif(WIN32)
endif()
endif()


Expand Down
20 changes: 14 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ option(ENABLE_SERVER "Enable Server" true)
option(ENABLE_MEM_DEBUG "Enable Memory Debug" false)
option(ENABLE_ASAN "Enable Address Sanitize" false)
option(ENABLE_WEBRTC "Enable WebRTC" false)
option(ENABLE_PLAYER "Enable Player" true)

# 添加git版本信息
set(COMMIT_HASH "Git_NotFound_Unkown_commit")
Expand Down Expand Up @@ -174,9 +175,9 @@ if (ENABLE_HLS)
list(APPEND LINK_LIB_LIST mpeg)
list(APPEND CXX_API_TARGETS mpeg)

if (WIN32)
if (MSVC)
set_target_properties(mpeg PROPERTIES COMPILE_FLAGS ${VS_FALGS})
endif (WIN32)
endif ()
endif ()

#添加mov、flv库用于MP4录制
Expand All @@ -198,9 +199,9 @@ if (ENABLE_MP4)
list(APPEND LINK_LIB_LIST mov flv)
list(APPEND CXX_API_TARGETS mov flv)

if (WIN32)
if (MSVC)
set_target_properties(mov flv PROPERTIES COMPILE_FLAGS ${VS_FALGS})
endif (WIN32)
endif ()
endif ()

#添加rtp库用于rtp转ps/ts
Expand Down Expand Up @@ -249,8 +250,10 @@ endif ()

if (WIN32)
list(APPEND LINK_LIB_LIST WS2_32 Iphlpapi shlwapi)
set_target_properties(zltoolkit PROPERTIES COMPILE_FLAGS ${VS_FALGS})
set_target_properties(zlmediakit PROPERTIES COMPILE_FLAGS ${VS_FALGS})
if (MSVC)
set_target_properties(zltoolkit PROPERTIES COMPILE_FLAGS ${VS_FALGS})
set_target_properties(zlmediakit PROPERTIES COMPILE_FLAGS ${VS_FALGS})
endif ()
elseif (NOT ANDROID OR IOS)
list(APPEND LINK_LIB_LIST pthread)
endif ()
Expand Down Expand Up @@ -291,4 +294,9 @@ if (NOT IOS)
if (ENABLE_SERVER)
add_subdirectory(server)
endif ()

#播放器
if (ENABLE_PLAYER)
add_subdirectory(player)
endif ()
endif ()
4 changes: 2 additions & 2 deletions api/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ foreach(TEST_SRC ${TEST_SRC_LIST})
set(exe_name api_tester_${TEST_EXE_NAME})
add_executable(${exe_name} ${TEST_SRC})

if(WIN32)
if(MSVC)
set_target_properties(${exe_name} PROPERTIES COMPILE_FLAGS ${VS_FALGS} )
endif(WIN32)
endif()

target_link_libraries(${exe_name} mk_api)
endforeach()
Expand Down
12 changes: 12 additions & 0 deletions cmake/FindSWRESAMPLE.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
find_path(SWRESAMPLE_INCLUDE_DIR
NAMES libswresample/swresample.h)

find_library(SWRESAMPLE_LIBRARY
NAMES swresample)

set(SWRESAMPLE_LIBRARIES ${SWRESAMPLE_LIBRARY})
set(SWRESAMPLE_INCLUDE_DIRS ${SWRESAMPLE_INCLUDE_DIR})

include(FindPackageHandleStandardArgs)

find_package_handle_standard_args(SWRESAMPLE DEFAULT_MSG SWRESAMPLE_LIBRARY SWRESAMPLE_INCLUDE_DIR)
126 changes: 126 additions & 0 deletions player/AudioSRC.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/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.
*/

#include "Util/logger.h"
#include "AudioSRC.h"
#include "SDLAudioDevice.h"

using namespace std;
using namespace toolkit;

AudioSRC::AudioSRC(AudioSRCDelegate *del) {
_delegate = del;
}

AudioSRC::~AudioSRC() {}

void AudioSRC::setOutputAudioConfig(const SDL_AudioSpec &cfg) {
int freq = _delegate->getPCMSampleRate();
int format = _delegate->getPCMFormat();
int channels = _delegate->getPCMChannel();
if (-1 == SDL_BuildAudioCVT(&_audio_cvt, format, channels, freq, cfg.format, cfg.channels, cfg.freq)) {
throw std::runtime_error("the format conversion is not supported");
}
InfoL << "audio cvt origin format, freq:" << freq << ", format:" << hex << format << dec << ", channels:" << channels;
InfoL << "audio cvt info, "
<< "needed:" << _audio_cvt.needed
<< ", src_format:" << hex << _audio_cvt.src_format
<< ", dst_format:" << _audio_cvt.dst_format << dec
<< ", rate_incr:" << _audio_cvt.rate_incr
<< ", len_mult:" << _audio_cvt.len_mult
<< ", len_ratio:" << _audio_cvt.len_ratio;
}

void AudioSRC::setEnableMix(bool flag) {
_enabled = flag;
}

int AudioSRC::getPCMData(char *buf, int size) {
if (!_enabled) {
return 0;
}
if (!_audio_cvt.needed) {
//获取原始数据,不需要频率转换
return _delegate->getPCMData(buf, size);
}

if ((int)(size / _audio_cvt.len_ratio) != _origin_size) {
_origin_size = size / _audio_cvt.len_ratio;
_origin_buf.reset(new char[std::max(_origin_size, size)], [](char *ptr) {
delete[] ptr;
});
InfoL << "origin pcm buffer size is:" << _origin_size << ", target pcm buffer size is:" << size;
}

auto origin_size = _delegate->getPCMData(_origin_buf.get(), _origin_size);
if (!origin_size) {
//获取数据失败
TraceL << "get empty pcm data";
return 0;
}

_audio_cvt.buf = (Uint8 *) _origin_buf.get();
_audio_cvt.len = origin_size;
if (0 != SDL_ConvertAudio(&_audio_cvt)) {
WarnL << "SDL_ConvertAudio failed!";
_audio_cvt.len_cvt = 0;
}
if (_audio_cvt.len_cvt) {
_target_buf.append(_origin_buf.get(), _audio_cvt.len_cvt);
}
if (_target_buf.size() < size) {
return 0;
}
memcpy(buf, _target_buf.data(), size);
_target_buf.erase(0, size);
return size;
}

////////////////////////////////////////////////////////////////////////

AudioPlayer::AudioPlayer() : AudioSRC(this) {
_device = SDLAudioDevice::Instance().shared_from_this();
}

AudioPlayer::~AudioPlayer() {
_device->delChannel(this);
}

void AudioPlayer::setup(int sample_rate, int channel, SDL_AudioFormat format) {
_sample_rate = sample_rate;
_channel = channel;
_format = format;
_device->addChannel(this);
}

SDL_AudioFormat AudioPlayer::getPCMFormat() {
return _format;
}

int AudioPlayer::getPCMSampleRate() {
return _sample_rate;
}

int AudioPlayer::getPCMChannel() {
return _channel;
}

int AudioPlayer::getPCMData(char *buf, int size) {
if (_buffer.size() < size) {
return 0;
}
memcpy(buf, _buffer.data(), size);
_buffer.erase(0, size);
return size;
}

void AudioPlayer::inputFrame(const char *data, size_t size){
_buffer.append(data, size);
}
86 changes: 86 additions & 0 deletions player/AudioSRC.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/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.
*/

#ifndef AUDIOSRC_H_
#define AUDIOSRC_H_

#include <memory>
#include <string>

#ifdef __cplusplus
extern "C" {
#endif
#include "SDL2/SDL.h"
#ifdef __cplusplus
}
#endif

#if defined(_WIN32)
#pragma comment(lib,"SDL2.lib")
#endif //defined(_WIN32)

#include "Network/Buffer.h"
#include "SDLAudioDevice.h"
#include "FFMpegDecoder.h"

using namespace std;
using namespace toolkit;

class AudioSRCDelegate {
public:
virtual ~AudioSRCDelegate() {};
virtual SDL_AudioFormat getPCMFormat() = 0;
virtual int getPCMSampleRate() = 0;
virtual int getPCMChannel() = 0;
virtual int getPCMData(char *buf, int size) = 0;
};

//该类实现pcm的重采样
class AudioSRC {
public:
typedef std::shared_ptr<AudioSRC> Ptr;
AudioSRC(AudioSRCDelegate *);
virtual ~AudioSRC();

void setEnableMix(bool flag);
void setOutputAudioConfig(const SDL_AudioSpec &cfg);
int getPCMData(char *buf, int size);

private:
bool _enabled = true;
int _origin_size = 0;
std::shared_ptr<char> _origin_buf;
AudioSRCDelegate *_delegate = nullptr;
BufferLikeString _target_buf;
SDL_AudioCVT _audio_cvt;
};

class AudioPlayer : public AudioSRC, private AudioSRCDelegate{
public:
AudioPlayer();
~AudioPlayer() override;

void setup(int sample_rate, int channel, SDL_AudioFormat format);
void inputFrame(const char *data, size_t size);

private:
SDL_AudioFormat getPCMFormat() override;
int getPCMSampleRate() override;
int getPCMChannel() override;
int getPCMData(char *buf, int size) override;

private:
int _sample_rate, _channel;
SDL_AudioFormat _format;
BufferLikeString _buffer;
SDLAudioDevice::Ptr _device;
};

#endif /* AUDIOSRC_H_ */
Loading

0 comments on commit 1b674a6

Please sign in to comment.