20190706宽 2023-10-12 08:58 采纳率: 0%
浏览 63
已结题

android hdmi 播放

背景:制作一个android电视的app,需要实现在app内播放HDMI视频源。
目前使用 TvView 可以播放HDMI源的画面,但没有声音该怎么办?代码如下:

img

img

补充:
audioManager.setParameters("audio_devices_out_active=AUDIO_HDMI");
按照上面这个思路找了网上的这个方法,但只成功了第一次,后面又再没声音了。
以下为目前代码


package com.example.hsy;

import static android.content.ContentValues.TAG;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvView;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;

public class Tv extends AppCompatActivity {
    private TvView tvView;
    private AudioManager audioManager;
    private AudioFocusRequest audioFocusRequest;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tv);
        tvView = (TvView)findViewById(R.id.tvView);
        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).setContentType(AudioAttributes.CONTENT_TYPE_MOVIE).build();
            audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK).setAudioAttributes(audioAttributes).setAcceptsDelayedFocusGain(true).setOnAudioFocusChangeListener(new AudioManager.OnAudioFocusChangeListener() {
                @Override
                public void onAudioFocusChange(int focusChange) {
                    // Handle audio focus changes if needed
                }
            }).build();
        }

        tvView.setCallback(new TvView.TvInputCallback() {
            @Override
            public void onVideoAvailable(String inputId) {
                super.onVideoAvailable(inputId);
                // Request audio focus
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    audioManager.requestAudioFocus(audioFocusRequest);
                } else {
                    audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
                }
            }

            @Override
            public void onVideoUnavailable(String inputId, int reason) {
                super.onVideoUnavailable(inputId, reason);
                // Abandon audio focus
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    audioManager.abandonAudioFocusRequest(audioFocusRequest);
                } else {
                    audioManager.abandonAudioFocus(null);
                }
            }
        });



        tvView.setStreamVolume(1.0f);
//        initData();
        playHdmi("com.mediatek.tvinput/.hdmi.HDMIInputService/HW5");


    }
    /**
     * 获取当前设备的输入源列表
     */
    private void initData() {
        TvInputManager tvInputManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
        if (tvInputManager == null) {
            return;
        }

        for (TvInputInfo info : tvInputManager.getTvInputList()) {
            Log.i(TAG, "id 信号源 :" + info.getId());
        }
    }

    /**
     * Build a special channel URI intended to be used with pass-through inputs. (e.g. HDMI)
     *
     * @param inputId The ID of the pass-through input to build a channels URI for.
     * @see TvInputInfo#isPassthroughInput()
     */
    public static Uri buildChannelUriForPassthroughInput(String inputId) {
        return TvContract.buildChannelUriForPassthroughInput(inputId);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void playHdmi(String inputId) {
        tvView.reset();
        // Build a special channel URI intended to be used with pass-through inputs. (e.g. HDMI)
        Uri uri = buildChannelUriForPassthroughInput(inputId);
        tvView.tune(inputId, uri,null);

// 设置音频流类型为HDMI音频输出
        audioManager.setParameters("audio_devices_out_active=AUDIO_HDMI");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Abandon audio focus when the activity is destroyed
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            audioManager.abandonAudioFocusRequest(audioFocusRequest);
        } else {
            audioManager.abandonAudioFocus(null);
        }
    }

}

  • 写回答

11条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2023-10-12 09:02
    关注
    获得1.50元问题酬金

    引自强大而免费的微信小程序:皆我百晓生。如有帮助,还望采纳。


    要在Android应用中播放HDMI源的声音,您可以尝试使用AudioManager类来控制音量。请修改您的代码如下:

    tvView = (TvView)findViewById(R.id.tvView);
    tvView.setStreamVolume(1.0f);
    initData();
    playHdmi("com.mediatek.tvinput/.hdmi.HDMIInputService/HW5");
    
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void playHdmi(string inputId) {
    tvView.reset();
    // Build a special channel URI intended to be used with pass-through inputs. (e.g. HDMI)
    Uri uri = buildChannelUriForPassthroughInput(inputId);
    tvView.tune(inputId, uri. params: null) ;
    
    // 获取系统的AudioManager实例
    AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    // 设置音频流类型为HDMI音频输出
    audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
    audioManager.setSpeakerphoneOn(false);
    audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 1.0f, 0);
    }
    
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 10月20日
  • 赞助了问题酬金15元 10月15日
  • 修改了问题 10月13日
  • 修改了问题 10月13日
  • 展开全部

悬赏问题

  • ¥15 系统 24h2 专业工作站版,浏览文件夹的图库,视频,图片之类的怎样删除?
  • ¥15 怎么把512还原为520格式
  • ¥15 MATLAB的动态模态分解出现错误,以CFX非定常模拟结果为快照
  • ¥15 求高通平台Softsim调试经验
  • ¥15 canal如何实现将mysql多张表(月表)采集入库到目标表中(一张表)?
  • ¥15 wpf ScrollViewer实现冻结左侧宽度w范围内的视图
  • ¥15 栅极驱动低侧烧毁MOSFET
  • ¥30 写segy数据时出错3
  • ¥100 linux下qt运行QCefView demo报错
  • ¥50 F1C100S下的红外解码IR_RX驱动问题