在Android中同时播放音频和视频

7

我想同时播放两个不同的文件。

我尝试找到播放器并尝试扩展默认播放器来实现这一点,但都没有成功。请告诉我最好的方法是什么,可以同时播放音频和视频?

之所以选择分开的文件,是为了节省空间,因为该应用程序将进行本地化,对于每种语言有多个音频文件而不是多个视频可以节省空间。这很重要,因为Android不允许下载超过50MB的应用程序大小。

任何关于此的帮助都将非常有用。如果提供给我此方面的代码,那将是极大的帮助。

谢谢您的提前帮助。


你无法通过这种方式准确地同步事物,而且大型视频应该以流媒体的方式播放。您是否有必要在应用程序中包含视频? - Dave
是的,我有一个新的原因,我正在制作一个应用程序,其中将包含视频文件,但音频将根据用户的语言环境进行设置,因此我需要在运行时同步这些文件。而且,视频对于用户理解我们传递给他们的内容非常重要。 - TheMohanAhuja
多个音频流可以编码到同一个媒体流中,在播放期间可以选择正确的音频流。Android的MediaPlayer通过selectTrack方法对此功能的支持有限(只能在准备状态下调用它来处理音频)。正确地编码视频是最好的选择。 - Dave
如果可能的话,您能否建议我使用哪种软件或方式对视频进行编码,并选择音频进行播放。如果有代码示例会更好。 - TheMohanAhuja
1
我建议您熟悉一下ffmpeg。他们的网站上有大量的文档。或者,如果您真的不喜欢命令行工具,您可能需要花一些钱购买类似Adobe Premiere这样的工具(我相信还有更便宜的选项)。无论哪种方式,您的目标是对一个带有一个视频流和几个音频流的文件进行编码。在那时,您应该能够使用MediaPlayer中的getTrackInfoselectTrack来在运行时选择正确的音频流。 - Dave
2个回答

1
你可以通过音频焦点来处理这个问题。两个或更多的Android应用程序可以同时将音频播放到同一个输出流中,系统会将所有内容混合在一起。虽然这在技术上令人印象深刻,但对用户来说可能非常烦人。为了避免每个音乐应用程序同时播放,Android引入了音频焦点的概念。一次只能有一个应用程序持有音频焦点。
当您的应用程序需要输出音频时,应请求音频焦点。当它具有焦点时,它可以播放声音。但是,在获取音频焦点后,您可能无法保持该焦点直到播放完毕。另一个应用程序可以请求焦点,这将取消您对音频焦点的控制。如果发生这种情况,您的应用程序应暂停播放或降低音量,以便让用户更容易地听到新的音频源。
从Android 8.0(API级别26)开始,当您调用requestAudioFocus()时,必须提供一个AudioFocusRequest参数。要释放音频焦点,请调用abandonAudioFocusRequest()方法,该方法也接受一个AudioFocusRequest作为其参数。请求和放弃焦点时应使用相同的AudioFocusRequest实例。
要创建一个 AudioFocusRequest,使用一个 AudioFocusRequest.Builder。由于焦点请求必须始终指定请求的类型,因此该类型包含在构造器中。使用构建器的方法设置请求的其他字段。
以下示例显示如何使用 AudioFocusRequest.Builder 构建 AudioFocusRequest 并请求和放弃音频焦点:
audioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
playbackAttributes = new AudioAttributes.Builder()
        .setUsage(AudioAttributes.USAGE_GAME)
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
        .build();
focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
        .setAudioAttributes(playbackAttributes)
        .setAcceptsDelayedFocusGain(true)
        .setOnAudioFocusChangeListener(afChangeListener, handler)
        .build();
mediaPlayer = new MediaPlayer();
final Object focusLock = new Object();

boolean playbackDelayed = false;
boolean playbackNowAuthorized = false;

// ...
int res = audioManager.requestAudioFocus(focusRequest);
synchronized(focusLock) {
    if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
        playbackNowAuthorized = false;
    } else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        playbackNowAuthorized = true;
        playbackNow();
    } else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
       playbackDelayed = true;
       playbackNowAuthorized = false;
    }
}

// ...
@Override
public void onAudioFocusChange(int focusChange) {
    switch (focusChange) {
        case AudioManager.AUDIOFOCUS_GAIN:
            if (playbackDelayed || resumeOnFocusGain) {
                synchronized(focusLock) {
                    playbackDelayed = false;
                    resumeOnFocusGain = false;
                }
                playbackNow();
            }
            break;
        case AudioManager.AUDIOFOCUS_LOSS:
            synchronized(focusLock) {
                resumeOnFocusGain = false;
                playbackDelayed = false;
            }
            pausePlayback();
            break;
        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
            synchronized(focusLock) {
                resumeOnFocusGain = true;
                playbackDelayed = false;
            }
            pausePlayback();
            break;
        case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
            // ... pausing or ducking depends on your app
            break;
        }
    }
}

希望这能帮到您!您还可以查看Android的官方文档。如果这不能解决问题,您可以查看此网站以及此网站获取更多文档资料。

0

播放音频:音轨引用 播放视频:媒体播放器引用

现在,您可以通过在视频视图中显示所需的视频来启动主线程,并在需要播放声音时开始播放音轨。棘手的部分将是将音频与视频同步。


是的,可以同时进行两件不同的事情,但是同步会很麻烦,这也会降低应用程序的质量。 - TheMohanAhuja
这是我选择创建类似应用程序的方式。我没有找到其他解决方案。 - Hitman
你能提供一些代码来完成这个任务吗?也许它可以帮助我。 - TheMohanAhuja
很抱歉我不能这样做。但是这个想法很简单。将视频作为链接播放到Video视图和Media Player中,当视频正在播放时,您有一个while(isPlaying)循环。在此循环中,您获取System.currentTimeMillis()并检查视频开始时间和当前时间之间的差异。如果差异等于您想要的偏移量,则开始播放音频。(假设您知道要播放声音文件的时间)。 - Hitman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接