繁体   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