CarGuo / GSYVideoPlayer

视频播放器(IJKplayer、ExoPlayer、MediaPlayer),HTTPS,16k page size,支持弹幕,外挂字幕,支持滤镜、水印、gif截图,片头广告、中间广告,多个同时播放,支持基本的拖动,声音、亮度调节,支持边播边缓存,支持视频自带rotation的旋转(90,270之类),重力旋转与手动旋转的同步支持,支持列表播放 ,列表全屏动画,视频加载速度,列表小窗口支持拖动,动画效果,调整比例,多分辨率切换,支持切换播放器,进度条小窗口预览,列表切换详情页面无缝播放,rtsp、concat、mpeg。
https://juejin.cn/user/817692379985752/posts
Apache License 2.0
20.13k stars 4.18k forks source link

怎么判断exoplayer硬解有声音没有画面? #3624

Closed zhengjiong closed 2 years ago

zhengjiong commented 2 years ago

问题描述:

使用exoplayer播放某些mpeg视频的时候有声音没有画面的时候想切换到ijk内核, 这个时候怎么判断他没有画面呢, 有什么好的办法吗?

出现问题的视频流

mpeg视频或其他不支持的视频编码

GSY依赖版本

implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-java:v8.3.2-release-jitpack' implementation 'com.github.CarGuo.GSYVideoPlayer:GSYVideoPlayer-exo2:v8.3.2-release-jitpack' implementation 'com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-ex_so:v8.3.2-release-jitpack'

CarGuo commented 2 years ago

目前我这边没想到有啥好的办法···

CarGuo commented 2 years ago

你可以尝试通过 getFormat 输出 Format,比如输出了 video/avc, avc1.4D401E ,这里就是 h264 ,你要自己做个映射

         if (binding.detailPlayer.getGSYVideoManager().getPlayer() instanceof Exo2PlayerManager) {
                        IjkExo2MediaPlayer player = ((IjkExo2MediaPlayer) binding.detailPlayer.getGSYVideoManager().getPlayer().getMediaPlayer());
                        MappingTrackSelector.MappedTrackInfo mappedTrackInfo = player.getTrackSelector().getCurrentMappedTrackInfo();
                        if (mappedTrackInfo != null) {
                            for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
                                TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(i);
                                if (C.TRACK_TYPE_AUDIO == mappedTrackInfo.getRendererType(i)) { //判断是否是音轨
                                    for (int j = 0; j < rendererTrackGroups.length; j++) {
                                        TrackGroup trackGroup = rendererTrackGroups.get(j);
                                        ///获取到 Format
                                        Debuger.printfError("####### Audio" + trackGroup.getFormat(0).toString() + " #######");
                                    }
                                }
                                if (C.TRACK_TYPE_VIDEO == mappedTrackInfo.getRendererType(i)) { //判断是否是音轨
                                    for (int j = 0; j < rendererTrackGroups.length; j++) {
                                        TrackGroup trackGroup = rendererTrackGroups.get(j);
                                        ///获取到 Format
                                        Debuger.printfError("####### Video" + trackGroup.getFormat(0).toString() + " #######");
                                    }
                                }
                            }
                        }
                    }

然后通过 类似方法尝试去匹配,这里是展示了个例子而已

   public static boolean isH265HardwareDecoderSupport() {
        MediaCodecList codecList = new MediaCodecList();
        MediaCodecInfo[] codecInfos = codecList.getCodecInfos();
        for (int i = 0; i < codecInfos.length; i++) {
            MediaCodecInfo codecInfo = codecInfos[i];
            if (!codecInfo.isEncoder() && (codecInfo.getName().contains("hevc")
                    && !isSoftwareCodec(codecInfo.getName()))) {
                return true;
            }
        }
        return false;
    }
    public boolean isSoftwareCodec(String codecName) {
        if (codecName.startsWith("OMX.google.")) {
            return true;
        }

        if (codecName.startsWith("OMX.")) {
            return false;
        }

        return true;
    }
zhengjiong commented 2 years ago

非常感谢

CarGuo commented 2 years ago

对应的 getMediaMimeType 可以参考

@Nullable
  public static String getMediaMimeType(@Nullable String codec) {
    if (codec == null) {
      return null;
    }
    codec = Ascii.toLowerCase(codec.trim());
    if (codec.startsWith("avc1") || codec.startsWith("avc3")) {
      return MimeTypes.VIDEO_H264;
    } else if (codec.startsWith("hev1") || codec.startsWith("hvc1")) {
      return MimeTypes.VIDEO_H265;
    } else if (codec.startsWith("dvav")
        || codec.startsWith("dva1")
        || codec.startsWith("dvhe")
        || codec.startsWith("dvh1")) {
      return MimeTypes.VIDEO_DOLBY_VISION;
    } else if (codec.startsWith("av01")) {
      return MimeTypes.VIDEO_AV1;
    } else if (codec.startsWith("vp9") || codec.startsWith("vp09")) {
      return MimeTypes.VIDEO_VP9;
    } else if (codec.startsWith("vp8") || codec.startsWith("vp08")) {
      return MimeTypes.VIDEO_VP8;
    } else if (codec.startsWith("mp4a")) {
      @Nullable String mimeType = null;
      if (codec.startsWith("mp4a.")) {
        @Nullable Mp4aObjectType objectType = getObjectTypeFromMp4aRFC6381CodecString(codec);
        if (objectType != null) {
          mimeType = getMimeTypeFromMp4ObjectType(objectType.objectTypeIndication);
        }
      }
      return mimeType == null ? MimeTypes.AUDIO_AAC : mimeType;
    } else if (codec.startsWith("mha1")) {
      return MimeTypes.AUDIO_MPEGH_MHA1;
    } else if (codec.startsWith("mhm1")) {
      return MimeTypes.AUDIO_MPEGH_MHM1;
    } else if (codec.startsWith("ac-3") || codec.startsWith("dac3")) {
      return MimeTypes.AUDIO_AC3;
    } else if (codec.startsWith("ec-3") || codec.startsWith("dec3")) {
      return MimeTypes.AUDIO_E_AC3;
    } else if (codec.startsWith(CODEC_E_AC3_JOC)) {
      return MimeTypes.AUDIO_E_AC3_JOC;
    } else if (codec.startsWith("ac-4") || codec.startsWith("dac4")) {
      return MimeTypes.AUDIO_AC4;
    } else if (codec.startsWith("dtsc")) {
      return MimeTypes.AUDIO_DTS;
    } else if (codec.startsWith("dtse")) {
      return MimeTypes.AUDIO_DTS_EXPRESS;
    } else if (codec.startsWith("dtsh") || codec.startsWith("dtsl")) {
      return MimeTypes.AUDIO_DTS_HD;
    } else if (codec.startsWith("dtsx")) {
      return MimeTypes.AUDIO_DTS_X;
    } else if (codec.startsWith("opus")) {
      return MimeTypes.AUDIO_OPUS;
    } else if (codec.startsWith("vorbis")) {
      return MimeTypes.AUDIO_VORBIS;
    } else if (codec.startsWith("flac")) {
      return MimeTypes.AUDIO_FLAC;
    } else if (codec.startsWith("stpp")) {
      return MimeTypes.APPLICATION_TTML;
    } else if (codec.startsWith("wvtt")) {
      return MimeTypes.TEXT_VTT;
    } else if (codec.contains("cea708")) {
      return MimeTypes.APPLICATION_CEA708;
    } else if (codec.contains("eia608") || codec.contains("cea608")) {
      return MimeTypes.APPLICATION_CEA608;
    } else {
      return getCustomMimeTypeForCodec(codec);
    }
  }