簡體   English   中英

如何同時啟用兩個ffplay窗口的音頻?(如何同時聽到視頻文件的音頻?)

[英]How to enable audio of two ffplay windows simultaneously?(How can I hear audio of the video files at the same time?)

當運行多個ffplay窗口時,僅啟用其中一個的音頻,但是我需要同時收聽所有這些音頻。

例如,我分別運行兩個命令行,如下所示:

//command line 1
ffplay -i video1.avi

//command line 2
ffplay -i video2.avi

如何同時聽到視頻文件的音頻?

我沒有在ffplay文檔中找到關於此的任何內容,因此我想更改ffplay源代碼。

這是event_loop函數(在event_loop中):

static void event_loop(VideoState *cur_stream)
{
SDL_Event event;
double incr, pos, frac;

for (;;) {
    double x;
    refresh_loop_wait_event(cur_stream, &event);
    switch (event.type) {
    case SDL_KEYDOWN:
        if (exit_on_keydown) {
            do_exit(cur_stream);
            break;
        }
        switch (event.key.keysym.sym) {
        case SDLK_ESCAPE:
        case SDLK_q:
            do_exit(cur_stream);
            break;
        case SDLK_f:
            toggle_full_screen(cur_stream);
            cur_stream->force_refresh = 1;
            break;
        case SDLK_p:
        case SDLK_SPACE:
            toggle_pause(cur_stream);
            break;
        case SDLK_m:
            toggle_mute(cur_stream);
            break;
        case SDLK_KP_MULTIPLY:
        case SDLK_0:
            update_volume(cur_stream, 1, SDL_VOLUME_STEP);
            break;
        case SDLK_KP_DIVIDE:
        case SDLK_9:
            update_volume(cur_stream, -1, SDL_VOLUME_STEP);
            break;
        case SDLK_s: // S: Step to next frame
            step_to_next_frame(cur_stream);
            break;
        case SDLK_a:
            stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
            break;
        case SDLK_v:
            stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
            break;
        case SDLK_c:
            stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
            stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
            stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
            break;
        case SDLK_t:
            stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
            break;
        case SDLK_w:
    #if CONFIG_AVFILTER
            if (cur_stream->show_mode == SHOW_MODE_VIDEO && cur_stream->vfilter_idx < nb_vfilters - 1) {
                if (++cur_stream->vfilter_idx >= nb_vfilters)
                    cur_stream->vfilter_idx = 0;
            } else {
                cur_stream->vfilter_idx = 0;
                toggle_audio_display(cur_stream);
            }
     #else
            toggle_audio_display(cur_stream);
     #endif
            break;
        case SDLK_PAGEUP:
            if (cur_stream->ic->nb_chapters <= 1) {
                incr = 600.0;
                goto do_seek;
            }
            seek_chapter(cur_stream, 1);
            break;
        case SDLK_PAGEDOWN:
            if (cur_stream->ic->nb_chapters <= 1) {
                incr = -600.0;
                goto do_seek;
            }
            seek_chapter(cur_stream, -1);
            break;
        case SDLK_LEFT:
            incr = -10.0;
            goto do_seek;
        case SDLK_RIGHT:
            incr = 10.0;
            goto do_seek;
        case SDLK_UP:
            incr = 60.0;
            goto do_seek;
        case SDLK_DOWN:
            incr = -60.0;
        do_seek:
                if (seek_by_bytes) {
                    pos = -1;
                    if (pos < 0 && cur_stream->video_stream >= 0)
                        pos = frame_queue_last_pos(&cur_stream->pictq);
                    if (pos < 0 && cur_stream->audio_stream >= 0)
                        pos = frame_queue_last_pos(&cur_stream->sampq);
                    if (pos < 0)
                        pos = avio_tell(cur_stream->ic->pb);
                    if (cur_stream->ic->bit_rate)
                        incr *= cur_stream->ic->bit_rate / 8.0;
                    else
                        incr *= 180000.0;
                    pos += incr;
                    stream_seek(cur_stream, pos, incr, 1);
                } else {
                    pos = get_master_clock(cur_stream);
                    if (isnan(pos))
                        pos = (double)cur_stream->seek_pos / AV_TIME_BASE;
                    pos += incr;
                    if (cur_stream->ic->start_time != AV_NOPTS_VALUE && pos < cur_stream->ic->start_time / (double)AV_TIME_BASE)
                        pos = cur_stream->ic->start_time / (double)AV_TIME_BASE;
                    stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
                }
            break;
        default:
            break;
        }
        break;
    case SDL_VIDEOEXPOSE:
        cur_stream->force_refresh = 1;
        break;
    case SDL_MOUSEBUTTONDOWN:
        if (exit_on_mousedown) {
            do_exit(cur_stream);
            break;
        }
    case SDL_MOUSEMOTION:
        if (cursor_hidden) {
            SDL_ShowCursor(1);
            cursor_hidden = 0;
        }
        cursor_last_shown = av_gettime_relative();
        if (event.type == SDL_MOUSEBUTTONDOWN) {
            x = event.button.x;
        } else {
            if (event.motion.state != SDL_PRESSED)
                break;
            x = event.motion.x;
        }
            if (seek_by_bytes || cur_stream->ic->duration <= 0) {
                uint64_t size =  avio_size(cur_stream->ic->pb);
                stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
            } else {
                int64_t ts;
                int ns, hh, mm, ss;
                int tns, thh, tmm, tss;
                tns  = cur_stream->ic->duration / 1000000LL;
                thh  = tns / 3600;
                tmm  = (tns % 3600) / 60;
                tss  = (tns % 60);
                frac = x / cur_stream->width;
                ns   = frac * tns;
                hh   = ns / 3600;
                mm   = (ns % 3600) / 60;
                ss   = (ns % 60);
                av_log(NULL, AV_LOG_INFO,
                       "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
                        hh, mm, ss, thh, tmm, tss);
                ts = frac * cur_stream->ic->duration;
                if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
                    ts += cur_stream->ic->start_time;
                stream_seek(cur_stream, ts, 0, 0);
            }
        break;
    case SDL_VIDEORESIZE:
            screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
                                      SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
            if (!screen) {
                av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
                do_exit(cur_stream);
            }
            screen_width  = cur_stream->width  = screen->w;
            screen_height = cur_stream->height = screen->h;
            cur_stream->force_refresh = 1;
        break;
    case SDL_QUIT:
    case FF_QUIT_EVENT:
        do_exit(cur_stream);
        break;
    case FF_ALLOC_EVENT:
        alloc_picture(event.user.data1);
        break;
    default:
        break;
    }
}

}

但是我找不到在event_loop函數中更改活動窗口或失去焦點時導致禁用音頻的命令。

您可以為ffplay添加多個輸入文件,然后將不同的流“映射”在一起,但是如果您將alsa混音器作為默認音頻設備,則系統應自動為您混合音頻。 修改ffplay不是一件容易的事

這是您選擇輸出設備的方式https://ffmpeg.org/ffmpeg-devices.html#Examples-7

這是“合並”多個輸入的方式:

https://trac.ffmpeg.org/wiki/連接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM