日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

Windows

更新時(shí)間:

阿里云RTC為您提供了輸入外部音視頻流的功能。通過閱讀本文,您可以了解輸入外部音視頻流、視頻流數(shù)據(jù)輸出以及外部音頻輸入播放的方法。

使用場景

使用場景包括但不限于以下:

  • 需要將本地媒體文件(視頻/音頻)及第三方音視頻數(shù)據(jù),通過SDK傳輸?shù)竭h(yuǎn)端播放渲染,可使用音視頻外部輸入推流實(shí)現(xiàn)。

  • 需要在使用音頻外部輸入的同時(shí),本地播放(耳返)輸入內(nèi)容,可使用外部音頻輸入播放實(shí)現(xiàn)。

  • 需要將通信過程中視頻數(shù)據(jù)保存或輸出處理(外部渲染,修改內(nèi)容)時(shí),可使用視頻數(shù)據(jù)裸數(shù)據(jù)輸出實(shí)現(xiàn)。

輸入外部視頻數(shù)據(jù)推流

  1. 調(diào)用SetExternalVideoSource啟用外部視頻輸入推流。

    說明

    目前Windows端不支持texture模式。

  2. 應(yīng)用側(cè)持續(xù)調(diào)用接PushExternalVideoFrame,向 SDK 投遞視頻裸數(shù)據(jù),進(jìn)行推流,參數(shù) frame 傳入裸數(shù)據(jù)相關(guān)信息,參數(shù) track 指明推流 track 類型,與步驟1 中設(shè)置開啟的track類型保持一致。

    說明
    • 投遞視頻幀數(shù)據(jù)的頻率由應(yīng)用方控制,依據(jù)視頻源幀率保持間隔投遞,直至輸入停止。建議應(yīng)用側(cè)獨(dú)立開啟線程,進(jìn)行數(shù)據(jù)投遞,保證數(shù)據(jù)輸入及時(shí)性。

    • 目前 Windows 端支持輸入 YUV數(shù)據(jù)(格式I420),需要在參數(shù) frame 的裸數(shù)據(jù)信息中,指定 pixelFormat RtcEngineVideoI420frameTypeRtcEngineVideoFrameRaw

    • 賦值裸數(shù)據(jù)信息時(shí),需要數(shù)據(jù)指針、視頻寬高信息、stride 信息等完整傳入;旋轉(zhuǎn)角度 rotation 目前暫未支持設(shè)置,請保持默認(rèn)值 0;時(shí)間戳取當(dāng)期時(shí)間,單位為毫秒。

  3. 數(shù)據(jù)源輸入結(jié)束或應(yīng)用中止外部視頻輸入,調(diào)用接口SetExternalVideoSource關(guān)閉外部視頻輸入。

代碼示例:

ding::rtc::RtcEngine *mediaEngine =;
.....

// 1.啟用外部視頻輸入
mediaEngine->SetExternalVideoSource(true, ding::rtc::RtcEngineVideoTrackCamera); // camera track啟用外部輸入

.....

// 2.獨(dú)立線程推送外部視頻數(shù)據(jù)
int frameRate = 30; // 30 fps
void *buffer = malloc(bufsize);
do
{
    ding::rtc::RtcEngineVideoFrame frm;
    memset(&frm, 0, sizeof(frm));
    frm.frameType = ding::rtc::RtcEngineVideoFrameRaw;
    frm.pixelFormat = ding::rtc::RtcEngineVideoI420;
    frm.timestamp = now;
    frm.width = // pic width;
    frm.height = // pic height;
    frm.rotation = 0;
    frm.count = count;
    frm.stride[0] = // ybuffer stride;
    frm.stride[1] = // ubuffer stride;
    frm.stride[2] = // vbuffer stride;
    frm.data = buffer;
    mediaEngine->PushExternalVideoFrame(&frm, ding::rtc::RtcEngineVideoTrackCamera);

    // 控制幀數(shù)據(jù)投遞頻率
    Sleep(1000 / frameRate);
    /* 產(chǎn)品代碼用控制幀率比較復(fù)雜一些,不能用Sleep(frame_duration)方式,
     * 因?yàn)镾leep非常不準(zhǔn)
    int64_t now = osal_get_time_ms();
    if (now - startTime < frameCount * frameDurationMs) {
        // 時(shí)間未到,再等一會(huì)
        osal_sleep_ms(2);
        continue;
    }
    */
} while (more);
free(buffer);
.....

// 3.停止外部視頻輸入
mediaEngine->SetExternalVideoSource(false, ding::rtc::RtcEngineVideoTrackCamera);

輸入外部音頻數(shù)據(jù)推流

  1. 調(diào)用接口SetExternalAudioSource啟用外部音頻輸入推流。

  2. 應(yīng)用側(cè)持續(xù)調(diào)用PushExternalAudioFrame接口,向 SDK 投遞音頻PCM 數(shù)據(jù),參數(shù)frame帶入音頻數(shù)據(jù)。

    說明
    • 投遞音頻裸數(shù)據(jù)的頻率由應(yīng)用方控制,每次投遞數(shù)據(jù)量不要超過 240ms 的音頻數(shù)據(jù)量,建議每次投遞 20ms 的音頻數(shù)據(jù),保持循環(huán)投遞直到結(jié)束。當(dāng)輸入數(shù)據(jù)頻率過快,SDK 緩存已滿暫時(shí)無法消費(fèi)數(shù)據(jù)時(shí),將丟失輸入音頻數(shù)據(jù)。

    • 與視頻輸入一致,同樣建議應(yīng)用側(cè)單獨(dú)開啟線程,投遞音頻裸數(shù)據(jù),直到輸入停止。

  3. 數(shù)據(jù)源輸入結(jié)束或應(yīng)用中止外部音頻輸入,調(diào)用接口SetExternalAudioSource關(guān)閉外部視音頻輸入。

代碼示例:

ding::rtc::RtcEngine *mediaEngine =;
.....

// 1.啟用外部視頻輸入
mediaEngine->SetExternalAudioSource(true, sample_rate, stereo ? 2 : 1);

.....


// 2.獨(dú)立線程推送外部音頻數(shù)據(jù)
void *ExtAudioSrc::worker(void *arg)
{
  ExtAudioSrc *pthis = (ExtAudioSrc *)arg;
  if (!pthis) {
    return NULL;
  }

  osal_thread_set_name("extaudiosrc");

  ding::rtc::RtcEngineAudioFrame frm;
  memset(&frm, 0, sizeof(frm));

  const int bytesPerSample = 2; // short
  const int frameMs = 20; // 20 ms per frame

  const int bufsize = pthis->sample_rate * frameMs / 1000 * (pthis->stereo ? 2 : 1) * bytesPerSample;

  FILE *fp = fopen(pthis->pcm_file_path.c_str(), "rb");
  if (fp == NULL) {
    return NULL;
  }

  void *buffer = malloc(bufsize);
  int64_t startTime = osal_get_time_ms();
  int count = 0;

  while (!pthis->quit_thread_flag_) {
    // maintain fps
    int64_t now = osal_get_time_ms();
    if ((now - startTime) * 1000 / frameMs < count * 1000) {
        osal_sleep_ms(2);
        continue;
    }

    // read pcm file
    int bytes = (int)fread(buffer, 1, bufsize, fp);
    if (bytes < bufsize) {
        // eof
        fseek(fp, 0, SEEK_SET);
        bytes = (int)fread(buffer, 1, bufsize, fp);
        if (bytes < bufsize) {
            break;
        }
    }

    count++;

    // callback
    frm.type = ding::rtc::RtcEngineAudioFramePcm16;
    frm.bytesPerSample = bytesPerSample;
    frm.samplesPerSec = pthis->sample_rate;
    frm.channels = (pthis->stereo ? 2 : 1);
    frm.samples = pthis->sample_rate * frameMs / 1000;
    frm.buffer = buffer;
    pthis->cb_on_one_frame_(&frm, pthis->cb_arg_);
  }

  if (buffer)
    free(buffer);
  if (fp != NULL)
    fclose(fp);

  return NULL;
}

void ExtAudioSrc::start_sampler(void on_frame(void *frm, void *arg), void *arg)
{
  if (sample_thread_ != NULL) {
    return;
  }

  cb_on_one_frame_ = on_frame;
  cb_arg_ = arg;

  quit_thread_flag_ = false;
  osal_thread_create(&sample_thread_, worker, this);
}
.....

ext_audio_src_.start_sampler([](void *frm, void *arg) {
      // 從文件讀取到一幀數(shù)據(jù),通過PushExternalAudioFrame傳遞給SDK
			ding::rtc::RtcEngine *engine = (ding::rtc::RtcEngine *)arg;
			engine->PushExternalAudioFrame((ding::rtc::RtcEngineAudioFrame *)frm);
			}, GetGlobalContext()->engine_);

// 3. 停止外部音頻輸入播放
void ExtAudioSrc::stop_sampler()
{
  if (sample_thread_ != NULL) {
    quit_thread_flag_ = true;
    osal_thread_join(sample_thread_, NULL);
    sample_thread_ = NULL;
  }
}

engine_->SetExternalAudioSource(false, 0, 0);
// stop reading thread
ext_audio_src_.stop_sampler();