mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-11-01 07:43:00 +00:00 
			
		
		
		
	Move stream's cache key generation in PlaybackResolver and improve PlaybackResolver's code
This commit is contained in:
		| @@ -3,8 +3,6 @@ package org.schabi.newpipe.player.helper; | ||||
| import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL; | ||||
| import static com.google.android.exoplayer2.Player.REPEAT_MODE_OFF; | ||||
| import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE; | ||||
| import static org.schabi.newpipe.extractor.stream.AudioStream.UNKNOWN_BITRATE; | ||||
| import static org.schabi.newpipe.extractor.stream.VideoStream.RESOLUTION_UNKNOWN; | ||||
| import static org.schabi.newpipe.player.Player.IDLE_WINDOW_FLAGS; | ||||
| import static org.schabi.newpipe.player.Player.PLAYER_TYPE; | ||||
| import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_ALWAYS; | ||||
| @@ -47,11 +45,9 @@ import com.google.android.exoplayer2.util.MimeTypes; | ||||
| import org.schabi.newpipe.R; | ||||
| import org.schabi.newpipe.extractor.InfoItem; | ||||
| import org.schabi.newpipe.extractor.MediaFormat; | ||||
| import org.schabi.newpipe.extractor.stream.AudioStream; | ||||
| import org.schabi.newpipe.extractor.stream.StreamInfo; | ||||
| import org.schabi.newpipe.extractor.stream.StreamInfoItem; | ||||
| import org.schabi.newpipe.extractor.stream.SubtitlesStream; | ||||
| import org.schabi.newpipe.extractor.stream.VideoStream; | ||||
| import org.schabi.newpipe.extractor.utils.Utils; | ||||
| import org.schabi.newpipe.player.MainPlayer; | ||||
| import org.schabi.newpipe.player.Player; | ||||
| @@ -197,52 +193,6 @@ public final class PlayerHelper { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     public static String cacheKeyOf(@NonNull final StreamInfo info, | ||||
|                                     @NonNull final VideoStream videoStream) { | ||||
|         String cacheKey = info.getUrl() + " " + videoStream.getId(); | ||||
|  | ||||
|         final String resolution = videoStream.getResolution(); | ||||
|         final MediaFormat mediaFormat = videoStream.getFormat(); | ||||
|         if (resolution.equals(RESOLUTION_UNKNOWN) && mediaFormat == null) { | ||||
|             // The hash code is only used in the cache key in the case when the resolution and the | ||||
|             // media format are unknown | ||||
|             cacheKey += " " + videoStream.hashCode(); | ||||
|         } else { | ||||
|             if (mediaFormat != null) { | ||||
|                 cacheKey += " " + videoStream.getFormat().getName(); | ||||
|             } | ||||
|             if (!resolution.equals(RESOLUTION_UNKNOWN)) { | ||||
|                 cacheKey += " " + resolution; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return cacheKey; | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     public static String cacheKeyOf(@NonNull final StreamInfo info, | ||||
|                                     @NonNull final AudioStream audioStream) { | ||||
|         String cacheKey = info.getUrl() + " " + audioStream.getId(); | ||||
|  | ||||
|         final int averageBitrate = audioStream.getAverageBitrate(); | ||||
|         final MediaFormat mediaFormat = audioStream.getFormat(); | ||||
|         if (averageBitrate == UNKNOWN_BITRATE && mediaFormat == null) { | ||||
|             // The hash code is only used in the cache key in the case when the resolution and the | ||||
|             // media format are unknown | ||||
|             cacheKey += " " + audioStream.hashCode(); | ||||
|         } else { | ||||
|             if (mediaFormat != null) { | ||||
|                 cacheKey += " " + audioStream.getFormat().getName(); | ||||
|             } | ||||
|             if (averageBitrate != UNKNOWN_BITRATE) { | ||||
|                 cacheKey += " " + averageBitrate; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return cacheKey; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Given a {@link StreamInfo} and the existing queue items, | ||||
|      * provide the {@link SinglePlayQueue} consisting of the next video for auto queueing. | ||||
|   | ||||
| @@ -13,7 +13,6 @@ import com.google.android.exoplayer2.source.MediaSource; | ||||
| import org.schabi.newpipe.extractor.stream.AudioStream; | ||||
| import org.schabi.newpipe.extractor.stream.StreamInfo; | ||||
| import org.schabi.newpipe.player.helper.PlayerDataSource; | ||||
| import org.schabi.newpipe.player.helper.PlayerHelper; | ||||
| import org.schabi.newpipe.player.mediaitem.MediaItemTag; | ||||
| import org.schabi.newpipe.player.mediaitem.StreamInfoTag; | ||||
| import org.schabi.newpipe.util.ListHelper; | ||||
| @@ -57,7 +56,7 @@ public class AudioPlaybackResolver implements PlaybackResolver { | ||||
|  | ||||
|         try { | ||||
|             return PlaybackResolver.buildMediaSource( | ||||
|                     dataSource, audio, info, PlayerHelper.cacheKeyOf(info, audio), tag); | ||||
|                     dataSource, audio, info, PlaybackResolver.cacheKeyOf(info, audio), tag); | ||||
|         } catch (final IOException e) { | ||||
|             Log.e(TAG, "Unable to create audio source:", e); | ||||
|             return null; | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| package org.schabi.newpipe.player.resolver; | ||||
|  | ||||
| import static org.schabi.newpipe.extractor.stream.AudioStream.UNKNOWN_BITRATE; | ||||
| import static org.schabi.newpipe.extractor.stream.VideoStream.RESOLUTION_UNKNOWN; | ||||
| import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; | ||||
| import static org.schabi.newpipe.player.helper.PlayerDataSource.LIVE_STREAM_EDGE_GAP_MILLIS; | ||||
|  | ||||
| @@ -20,6 +22,7 @@ import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; | ||||
| import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest; | ||||
| import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser; | ||||
|  | ||||
| import org.schabi.newpipe.extractor.MediaFormat; | ||||
| import org.schabi.newpipe.extractor.ServiceList; | ||||
| import org.schabi.newpipe.extractor.services.youtube.ItagItem; | ||||
| import org.schabi.newpipe.extractor.services.youtube.dashmanifestcreators.CreationException; | ||||
| @@ -49,6 +52,79 @@ import java.util.Objects; | ||||
| public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> { | ||||
|     String TAG = PlaybackResolver.class.getSimpleName(); | ||||
|  | ||||
|     @NonNull | ||||
|     private static StringBuilder commonCacheKeyOf(@NonNull final StreamInfo info, | ||||
|                                                   @NonNull final Stream stream, | ||||
|                                                   final boolean resolutionOrBitrateUnknown) { | ||||
|         // stream info service id | ||||
|         final StringBuilder cacheKey = new StringBuilder(info.getServiceId()); | ||||
|  | ||||
|         // stream info id | ||||
|         cacheKey.append(" "); | ||||
|         cacheKey.append(info.getId()); | ||||
|  | ||||
|         // stream id (even if unknown) | ||||
|         cacheKey.append(" "); | ||||
|         cacheKey.append(stream.getId()); | ||||
|  | ||||
|         // mediaFormat (if not null) | ||||
|         final MediaFormat mediaFormat = stream.getFormat(); | ||||
|         if (mediaFormat != null) { | ||||
|             cacheKey.append(" "); | ||||
|             cacheKey.append(mediaFormat.getName()); | ||||
|         } | ||||
|  | ||||
|         // content (only if other information is missing) | ||||
|         // If the media format and the resolution/bitrate are both missing, then we don't have | ||||
|         // enough information to distinguish this stream from other streams. | ||||
|         // So, only in that case, we use the content (i.e. url or manifest) to differentiate | ||||
|         // between streams. | ||||
|         // Note that if the content were used even when other information is present, then two | ||||
|         // streams with the same stats but with different contents (e.g. because the url was | ||||
|         // refreshed) will be considered different (i.e. with a different cacheKey), making the | ||||
|         // cache useless. | ||||
|         if (resolutionOrBitrateUnknown && mediaFormat == null) { | ||||
|             cacheKey.append(" "); | ||||
|             Objects.hash(stream.getContent(), stream.getManifestUrl()); | ||||
|         } | ||||
|  | ||||
|         return cacheKey; | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     static String cacheKeyOf(@NonNull final StreamInfo info, | ||||
|                              @NonNull final VideoStream videoStream) { | ||||
|         final boolean resolutionUnknown = videoStream.getResolution().equals(RESOLUTION_UNKNOWN); | ||||
|         final StringBuilder cacheKey = commonCacheKeyOf(info, videoStream, resolutionUnknown); | ||||
|  | ||||
|         // resolution (if known) | ||||
|         if (!resolutionUnknown) { | ||||
|             cacheKey.append(" "); | ||||
|             cacheKey.append(videoStream.getResolution()); | ||||
|         } | ||||
|  | ||||
|         // isVideoOnly | ||||
|         cacheKey.append(" "); | ||||
|         cacheKey.append(videoStream.isVideoOnly()); | ||||
|  | ||||
|         return cacheKey.toString(); | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     static String cacheKeyOf(@NonNull final StreamInfo info, | ||||
|                              @NonNull final AudioStream audioStream) { | ||||
|         final boolean averageBitrateUnknown = audioStream.getAverageBitrate() == UNKNOWN_BITRATE; | ||||
|         final StringBuilder cacheKey = commonCacheKeyOf(info, audioStream, averageBitrateUnknown); | ||||
|  | ||||
|         // averageBitrate (if known) | ||||
|         if (!averageBitrateUnknown) { | ||||
|             cacheKey.append(" "); | ||||
|             cacheKey.append(audioStream.getAverageBitrate()); | ||||
|         } | ||||
|  | ||||
|         return cacheKey.toString(); | ||||
|     } | ||||
|  | ||||
|     @Nullable | ||||
|     static MediaSource maybeBuildLiveMediaSource(@NonNull final PlayerDataSource dataSource, | ||||
|                                                  @NonNull final StreamInfo info) { | ||||
|   | ||||
| @@ -95,7 +95,7 @@ public class VideoPlaybackResolver implements PlaybackResolver { | ||||
|         if (video != null) { | ||||
|             try { | ||||
|                 final MediaSource streamSource = PlaybackResolver.buildMediaSource( | ||||
|                         dataSource, video, info, PlayerHelper.cacheKeyOf(info, video), tag); | ||||
|                         dataSource, video, info, PlaybackResolver.cacheKeyOf(info, video), tag); | ||||
|                 mediaSources.add(streamSource); | ||||
|             } catch (final IOException e) { | ||||
|                 Log.e(TAG, "Unable to create video source:", e); | ||||
| @@ -114,7 +114,7 @@ public class VideoPlaybackResolver implements PlaybackResolver { | ||||
|         if (audio != null && (video == null || video.isVideoOnly())) { | ||||
|             try { | ||||
|                 final MediaSource audioSource = PlaybackResolver.buildMediaSource( | ||||
|                         dataSource, audio, info, PlayerHelper.cacheKeyOf(info, audio), tag); | ||||
|                         dataSource, audio, info, PlaybackResolver.cacheKeyOf(info, audio), tag); | ||||
|                 mediaSources.add(audioSource); | ||||
|                 streamSourceType = SourceType.VIDEO_WITH_SEPARATED_AUDIO; | ||||
|             } catch (final IOException e) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Stypox
					Stypox