diff --git a/components/video-player/Controls.tsx b/components/video-player/Controls.tsx index 14e0f9a5..2ab0ba23 100644 --- a/components/video-player/Controls.tsx +++ b/components/video-player/Controls.tsx @@ -49,6 +49,12 @@ import { VideoRef } from "react-native-video"; import * as DropdownMenu from "zeego/dropdown-menu"; import { Text } from "../common/Text"; import { Loader } from "../Loader"; +import BottomSheet, { + BottomSheetBackdrop, + BottomSheetBackdropProps, + BottomSheetModal, + BottomSheetView, +} from "@gorhom/bottom-sheet"; interface Props { item: BaseItemDto; @@ -391,6 +397,32 @@ export const Controls: React.FC = ({ )[]; }, [item, isVideoLoaded, subtitleTracks, mediaSource]); + /** + * Bottom sheet + */ + const bottomSheetModalRef = useRef(null); + + const handlePresentModalPress = useCallback(() => { + bottomSheetModalRef.current?.present(); + }, []); + + const handleSheetChanges = useCallback((index: number) => {}, []); + + const closeModal = useCallback(() => { + bottomSheetModalRef.current?.dismiss(); + }, []); + + const renderBackdrop = useCallback( + (props: BottomSheetBackdropProps) => ( + + ), + [] + ); + return ( = ({ height: "100%", }} > - {/* */} + + + + Audio Tracks + + {audioTracks?.map((track, index) => ( + { + setAudioTrack && setAudioTrack(track.index); + closeModal(); + }} + className="border border-neutral-700 rounded-lg p-4 mb-2 bg-neutral-800" + > + + {track.name} {track.language ? `(${track.language})` : null} + + + ))} + + Subtitles + {allSubtitleTracks?.map((sub, index) => ( + { + if (sub.isExternal) { + setSubtitleURL && + setSubtitleURL(api?.basePath + sub.deliveryUrl, sub.name); + } else { + setSubtitleTrack && setSubtitleTrack(sub.index); + } + closeModal(); + }} + className="border border-neutral-700 rounded-lg p-4 mb-2 bg-neutral-800" + > + {sub.name} + + ))} + + = ({ }} className="p-4" > - + { + handlePresentModalPress(); + }} + className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2" + > + + + {/* - console.log("open settings")} - className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2" - > - - = ({ - + */} { maxStreamingBitrate: bitrateValue, mediaSourceId: mediaSourceId, subtitleStreamIndex: subtitleIndex, - deviceProfile: native, + deviceProfile: android, }); if (!res) return null; @@ -383,6 +376,8 @@ const Player = () => { height: "100%", width: "100%", position: "absolute", + top: 0, + left: 0, zIndex: 0, }} > @@ -396,7 +391,9 @@ const Player = () => { }} resizeMode={ignoreSafeAreas ? "cover" : "contain"} onProgress={onProgress} - onError={() => {}} + onError={(e) => { + console.error("Error playing video", e); + }} onLoad={() => { if (firstTime.current === true) { play(); @@ -468,7 +465,7 @@ const Player = () => { console.log("setAudioTrack ~", i); setSelectedAudioTrack({ type: SelectedTrackType.INDEX, - value: 10, + value: i, }); }} /> diff --git a/utils/profiles/android.js b/utils/profiles/android.js new file mode 100644 index 00000000..19665c7f --- /dev/null +++ b/utils/profiles/android.js @@ -0,0 +1,143 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +import MediaTypes from "../../constants/MediaTypes"; + +/** + * Device profile for Native video player + */ +export default { + Name: "1. Native iOS Video Profile", + MaxStaticBitrate: 100000000, + MaxStreamingBitrate: 120000000, + MusicStreamingTranscodingBitrate: 384000, + CodecProfiles: [ + { + Type: MediaTypes.Video, + Codec: "h264,h265,hevc,mpeg4,divx,xvid,wmv,vc1,vp8,vp9,av1", + }, + { + Type: MediaTypes.Audio, + Codec: "aac,mp3,flac,alac,opus,vorbis,pcm,wma", + }, + ], + DirectPlayProfiles: [ + { + Type: MediaTypes.Video, + Container: "mp4,mkv,avi,mov,flv,ts,m2ts,webm,ogv,3gp", + VideoCodec: "h264,h265,hevc,mpeg4,divx,xvid,wmv,vc1,vp8,vp9,av1", + AudioCodec: "aac,mp3,flac,alac,opus,vorbis,wma", + }, + { + Type: MediaTypes.Audio, + Container: "mp3,aac,flac,alac,wav,ogg,wma", + AudioCodec: "mp3,aac,flac,alac,opus,vorbis,wma,pcm", + }, + ], + TranscodingProfiles: [ + { + Type: MediaTypes.Video, + Context: "Streaming", + Protocol: "hls", + Container: "ts", + VideoCodec: "h264", + AudioCodec: "aac,mp3,ac3", + MaxAudioChannels: "8", + MinSegments: "2", + BreakOnNonKeyFrames: true, + }, + { + Type: MediaTypes.Audio, + Context: "Streaming", + Protocol: "http", + Container: "mp3", + AudioCodec: "mp3", + MaxAudioChannels: "2", + }, + ], + ResponseProfiles: [ + { + Container: "mkv", + MimeType: "video/x-matroska", + Type: MediaTypes.Video, + }, + { + Container: "mp4", + MimeType: "video/mp4", + Type: MediaTypes.Video, + }, + ], + SubtitleProfiles: [ + { Format: "srt", Method: "Embed" }, + { Format: "srt", Method: "External" }, + { Format: "srt", Method: "Encode" }, + { Format: "ass", Method: "Embed" }, + { Format: "ass", Method: "External" }, + { Format: "ass", Method: "Encode" }, + { Format: "ssa", Method: "Embed" }, + { Format: "ssa", Method: "External" }, + { Format: "ssa", Method: "Encode" }, + { Format: "sub", Method: "Embed" }, + { Format: "sub", Method: "External" }, + { Format: "sub", Method: "Encode" }, + { Format: "vtt", Method: "Embed" }, + { Format: "vtt", Method: "External" }, + { Format: "vtt", Method: "Encode" }, + { Format: "ttml", Method: "Embed" }, + { Format: "ttml", Method: "External" }, + { Format: "ttml", Method: "Encode" }, + { Format: "pgs", Method: "Embed" }, + { Format: "pgs", Method: "External" }, + { Format: "pgs", Method: "Encode" }, + { Format: "dvdsub", Method: "Embed" }, + { Format: "dvdsub", Method: "External" }, + { Format: "dvdsub", Method: "Encode" }, + { Format: "dvbsub", Method: "Embed" }, + { Format: "dvbsub", Method: "External" }, + { Format: "dvbsub", Method: "Encode" }, + { Format: "xsub", Method: "Embed" }, + { Format: "xsub", Method: "External" }, + { Format: "xsub", Method: "Encode" }, + { Format: "mov_text", Method: "Embed" }, + { Format: "mov_text", Method: "External" }, + { Format: "mov_text", Method: "Encode" }, + { Format: "scc", Method: "Embed" }, + { Format: "scc", Method: "External" }, + { Format: "scc", Method: "Encode" }, + { Format: "smi", Method: "Embed" }, + { Format: "smi", Method: "External" }, + { Format: "smi", Method: "Encode" }, + { Format: "teletext", Method: "Embed" }, + { Format: "teletext", Method: "External" }, + { Format: "teletext", Method: "Encode" }, + { Format: "microdvd", Method: "Embed" }, + { Format: "microdvd", Method: "External" }, + { Format: "microdvd", Method: "Encode" }, + { Format: "mpl2", Method: "Embed" }, + { Format: "mpl2", Method: "External" }, + { Format: "mpl2", Method: "Encode" }, + { Format: "pjs", Method: "Embed" }, + { Format: "pjs", Method: "External" }, + { Format: "pjs", Method: "Encode" }, + { Format: "realtext", Method: "Embed" }, + { Format: "realtext", Method: "External" }, + { Format: "realtext", Method: "Encode" }, + { Format: "stl", Method: "Embed" }, + { Format: "stl", Method: "External" }, + { Format: "stl", Method: "Encode" }, + { Format: "subrip", Method: "Embed" }, + { Format: "subrip", Method: "External" }, + { Format: "subrip", Method: "Encode" }, + { Format: "subviewer", Method: "Embed" }, + { Format: "subviewer", Method: "External" }, + { Format: "subviewer", Method: "Encode" }, + { Format: "text", Method: "Embed" }, + { Format: "text", Method: "External" }, + { Format: "text", Method: "Encode" }, + { Format: "vplayer", Method: "Embed" }, + { Format: "vplayer", Method: "External" }, + { Format: "vplayer", Method: "Encode" }, + ], +};