mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 20:25:34 +08:00
Enable audio transmission
This commit is contained in:
123
test/audio_capture/windows_capture.cpp
Normal file
123
test/audio_capture/windows_capture.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
extern "C" {
|
||||
#include <libavdevice/avdevice.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/log.h>
|
||||
#include <libswresample/swresample.h>
|
||||
}
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#pragma comment(lib, "avutil.lib")
|
||||
#pragma comment(lib, "avdevice.lib")
|
||||
#pragma comment(lib, "avformat.lib")
|
||||
#pragma comment(lib, "avcodec.lib")
|
||||
|
||||
#pragma comment(lib, "Winmm.lib")
|
||||
|
||||
using std::shared_ptr;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
void capture_audio() {
|
||||
// windows api <20><>ȡ<EFBFBD><C8A1>Ƶ<EFBFBD>豸<EFBFBD>б<EFBFBD><D0B1><EFBFBD>ffmpeg <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD>ṩ<EFBFBD><E1B9A9>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ƶ<EFBFBD>豸<EFBFBD><E8B1B8>api<70><69>
|
||||
int nDeviceNum = waveInGetNumDevs();
|
||||
vector<string> vecDeviceName;
|
||||
for (int i = 0; i < nDeviceNum; ++i) {
|
||||
WAVEINCAPS wic;
|
||||
waveInGetDevCaps(i, &wic, sizeof(wic));
|
||||
|
||||
// ת<><D7AA>utf-8
|
||||
int nSize = WideCharToMultiByte(CP_UTF8, 0, wic.szPname,
|
||||
wcslen(wic.szPname), NULL, 0, NULL, NULL);
|
||||
shared_ptr<char> spDeviceName(new char[nSize + 1]);
|
||||
memset(spDeviceName.get(), 0, nSize + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wic.szPname, wcslen(wic.szPname),
|
||||
spDeviceName.get(), nSize, NULL, NULL);
|
||||
vecDeviceName.push_back(spDeviceName.get());
|
||||
av_log(NULL, AV_LOG_DEBUG, "audio input device : %s \n",
|
||||
spDeviceName.get());
|
||||
}
|
||||
if (vecDeviceName.size() <= 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "not find audio input device.\n");
|
||||
return;
|
||||
}
|
||||
string sDeviceName = "audio=" + vecDeviceName[0]; // ʹ<>õ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ƶ<EFBFBD>豸
|
||||
|
||||
// ffmpeg
|
||||
avdevice_register_all(); // ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸
|
||||
AVInputFormat* ifmt =
|
||||
(AVInputFormat*)av_find_input_format("dshow"); // <20><><EFBFBD>òɼ<C3B2><C9BC><EFBFBD>ʽ dshow
|
||||
if (ifmt == NULL) {
|
||||
av_log(NULL, AV_LOG_ERROR, "av_find_input_format for dshow fail.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
AVFormatContext* fmt_ctx = NULL; // format <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int ret = avformat_open_input(&fmt_ctx, sDeviceName.c_str(), ifmt,
|
||||
NULL); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>豸
|
||||
if (ret != 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "avformat_open_input fail. return %d.\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
AVPacket pkt;
|
||||
|
||||
int64_t src_rate = 44100;
|
||||
int64_t dst_rate = 48000;
|
||||
SwrContext* swr_ctx = swr_alloc();
|
||||
|
||||
uint8_t** dst_data = NULL;
|
||||
int dst_linesize = 0;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
av_opt_set_int(swr_ctx, "in_channel_layout", AV_CH_LAYOUT_MONO, 0);
|
||||
av_opt_set_int(swr_ctx, "in_sample_rate", src_rate, 0);
|
||||
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
av_opt_set_int(swr_ctx, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
|
||||
av_opt_set_int(swr_ctx, "out_sample_rate", dst_rate, 0);
|
||||
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
// <20><>ʼ<EFBFBD><CABC>SwrContext
|
||||
swr_init(swr_ctx);
|
||||
|
||||
FILE* fp = fopen("dst.pcm", "wb");
|
||||
int count = 0;
|
||||
while (count++ < 10) {
|
||||
ret = av_read_frame(fmt_ctx, &pkt);
|
||||
if (ret != 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "av_read_frame fail, return %d .\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
int out_samples_per_channel =
|
||||
(int)av_rescale_rnd(1024, dst_rate, src_rate, AV_ROUND_UP);
|
||||
int out_buffer_size = av_samples_get_buffer_size(
|
||||
NULL, 1, out_samples_per_channel, AV_SAMPLE_FMT_S16, 0);
|
||||
// uint8_t* out_buffer = (uint8_t*)av_malloc(out_buffer_size);
|
||||
ret = av_samples_alloc_array_and_samples(
|
||||
&dst_data, &dst_linesize, 2, out_buffer_size, AV_SAMPLE_FMT_S16, 0);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
||||
swr_convert(swr_ctx, dst_data, out_samples_per_channel,
|
||||
(const uint8_t**)&pkt.data, 1024);
|
||||
|
||||
fwrite(dst_data[1], 1, out_buffer_size, fp);
|
||||
av_packet_unref(&pkt); // <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>pkt<6B><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>й¶
|
||||
}
|
||||
fflush(fp); // ˢ<><CBA2><EFBFBD>ļ<EFBFBD>io<69><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
fclose(fp);
|
||||
|
||||
avformat_close_input(&fmt_ctx);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
av_log_set_level(AV_LOG_DEBUG); // <20><><EFBFBD><EFBFBD>ffmpeg<65><67>־<EFBFBD><D6BE><EFBFBD>ȼ<EFBFBD>
|
||||
capture_audio();
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
Reference in New Issue
Block a user