mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
WIP
This commit is contained in:
@@ -6,7 +6,7 @@ import { Loader } from "@/components/Loader";
|
||||
import { MediaListSection } from "@/components/medialists/MediaListSection";
|
||||
import { Colors } from "@/constants/Colors";
|
||||
import { TAB_HEIGHT } from "@/constants/Values";
|
||||
import { hello } from "@/modules/vlc-player";
|
||||
import { hello, VlcPlayerView } from "@/modules/vlc-player";
|
||||
import { useDownload } from "@/providers/DownloadProvider";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
@@ -383,9 +383,27 @@ export default function index() {
|
||||
);
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text>{hello()}</Text>
|
||||
</View>
|
||||
<ScrollView
|
||||
nestedScrollEnabled
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={loading} onRefresh={refetch} />
|
||||
}
|
||||
key={"home"}
|
||||
contentContainerStyle={{
|
||||
paddingLeft: insets.left,
|
||||
paddingRight: insets.right,
|
||||
paddingBottom: 16,
|
||||
}}
|
||||
style={{
|
||||
marginBottom: TAB_HEIGHT,
|
||||
}}
|
||||
>
|
||||
<View className="flex flex-col space-y-4">
|
||||
<Text>{hello()}</Text>
|
||||
<VlcPlayerView source="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" />
|
||||
</View>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { NativeModulesProxy, EventEmitter, Subscription } from 'expo-modules-core';
|
||||
import {
|
||||
NativeModulesProxy,
|
||||
EventEmitter,
|
||||
Subscription,
|
||||
} from "expo-modules-core";
|
||||
|
||||
// Import the native module. On web, it will be resolved to VlcPlayer.web.ts
|
||||
// and on native platforms to VlcPlayer.ts
|
||||
import VlcPlayerModule from './src/VlcPlayerModule';
|
||||
import VlcPlayerView from './src/VlcPlayerView';
|
||||
import { ChangeEventPayload, VlcPlayerViewProps } from './src/VlcPlayer.types';
|
||||
import VlcPlayerModule from "./src/VlcPlayerModule";
|
||||
import VlcPlayerView from "./src/VlcPlayerView";
|
||||
import { ChangeEventPayload, VlcPlayerViewProps } from "./src/VlcPlayer.types";
|
||||
|
||||
// Get the native constant value.
|
||||
export const PI = VlcPlayerModule.PI;
|
||||
@@ -17,10 +21,14 @@ export async function setValueAsync(value: string) {
|
||||
return await VlcPlayerModule.setValueAsync(value);
|
||||
}
|
||||
|
||||
const emitter = new EventEmitter(VlcPlayerModule ?? NativeModulesProxy.VlcPlayer);
|
||||
const emitter = new EventEmitter(
|
||||
VlcPlayerModule ?? NativeModulesProxy.VlcPlayer
|
||||
);
|
||||
|
||||
export function addChangeListener(listener: (event: ChangeEventPayload) => void): Subscription {
|
||||
return emitter.addListener<ChangeEventPayload>('onChange', listener);
|
||||
export function addChangeListener(
|
||||
listener: (event: ChangeEventPayload) => void
|
||||
): Subscription {
|
||||
return emitter.addListener<ChangeEventPayload>("onChange", listener);
|
||||
}
|
||||
|
||||
export { VlcPlayerView, VlcPlayerViewProps, ChangeEventPayload };
|
||||
|
||||
@@ -9,36 +9,14 @@ public class VlcPlayerModule: Module {
|
||||
// Can be inferred from module's class name, but it's recommended to set it explicitly for clarity.
|
||||
// The module will be accessible from `requireNativeModule('VlcPlayer')` in JavaScript.
|
||||
Name("VlcPlayer")
|
||||
|
||||
// Sets constant properties on the module. Can take a dictionary or a closure that returns a dictionary.
|
||||
Constants([
|
||||
"PI": Double.pi
|
||||
])
|
||||
|
||||
// Defines event names that the module can send to JavaScript.
|
||||
Events("onChange")
|
||||
|
||||
// Defines a JavaScript synchronous function that runs the native code on the JavaScript thread.
|
||||
Function("hello") {
|
||||
return "Hello world! 👋"
|
||||
}
|
||||
|
||||
// Defines a JavaScript function that always returns a Promise and whose native code
|
||||
// is by default dispatched on the different thread than the JavaScript runtime runs on.
|
||||
AsyncFunction("setValueAsync") { (value: String) in
|
||||
// Send an event to JavaScript.
|
||||
self.sendEvent("onChange", [
|
||||
"value": value
|
||||
])
|
||||
}
|
||||
|
||||
// Enables the module to be used as a native view. Definition components that are accepted as part of the
|
||||
// view definition: Prop, Events.
|
||||
View(VlcPlayerView.self) {
|
||||
// Defines a setter for the `name` prop.
|
||||
Prop("name") { (view: VlcPlayerView, prop: String) in
|
||||
print(prop)
|
||||
Prop("source") { (view: VlcPlayerView, source: String) in
|
||||
view.setSource(source)
|
||||
}
|
||||
}
|
||||
|
||||
Function("hello") {
|
||||
return "hello from native ios"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,77 @@
|
||||
import ExpoModulesCore
|
||||
import UIKit
|
||||
import MobileVLCKit
|
||||
|
||||
// This view will be used as a native component. Make sure to inherit from `ExpoView`
|
||||
// to apply the proper styling (e.g. border radius and shadows).
|
||||
class VlcPlayerView: ExpoView {
|
||||
|
||||
}
|
||||
class VlcPlayerView: ExpoView, VLCMediaPlayerDelegate {
|
||||
private var mediaPlayer: VLCMediaPlayer?
|
||||
private var movieView: UIView?
|
||||
|
||||
required init(appContext: AppContext? = nil) {
|
||||
super.init(appContext: appContext)
|
||||
DispatchQueue.main.async {
|
||||
self.setupView()
|
||||
self.backgroundColor = UIColor.black // Set background color to black
|
||||
}
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
DispatchQueue.main.async {
|
||||
self.movieView = UIView()
|
||||
self.movieView?.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
if let movieView = self.movieView {
|
||||
self.addSubview(movieView)
|
||||
NSLayoutConstraint.activate([
|
||||
movieView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
|
||||
movieView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
|
||||
movieView.topAnchor.constraint(equalTo: self.topAnchor),
|
||||
movieView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
|
||||
])
|
||||
}
|
||||
|
||||
self.setupMediaPlayer()
|
||||
}
|
||||
}
|
||||
|
||||
private func setupMediaPlayer() {
|
||||
DispatchQueue.main.async {
|
||||
self.mediaPlayer = VLCMediaPlayer()
|
||||
self.mediaPlayer?.delegate = self
|
||||
self.mediaPlayer?.drawable = self.movieView
|
||||
print("Media player setup on main thread: \(Thread.isMainThread)")
|
||||
}
|
||||
}
|
||||
|
||||
@objc func setSource(_ source: String) {
|
||||
DispatchQueue.main.async {
|
||||
print("Setting media source on main thread: \(Thread.isMainThread)")
|
||||
if let url = URL(string: source) {
|
||||
self.mediaPlayer?.media = VLCMedia(url: url)
|
||||
print("Media set, now playing...")
|
||||
self.mediaPlayer?.play()
|
||||
} else {
|
||||
print("Invalid URL.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc func handlePlayPause() {
|
||||
DispatchQueue.main.async {
|
||||
print("Handling play/pause on main thread: \(Thread.isMainThread)")
|
||||
if self.mediaPlayer?.isPlaying == true {
|
||||
self.mediaPlayer?.pause()
|
||||
} else {
|
||||
self.mediaPlayer?.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mediaPlayerStateChanged(_ aNotification: Notification!) {
|
||||
DispatchQueue.main.async {
|
||||
print("Media player state changed on main thread: \(Thread.isMainThread)")
|
||||
if self.mediaPlayer?.state == .stopped {
|
||||
print("Media player stopped")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,5 +3,5 @@ export type ChangeEventPayload = {
|
||||
};
|
||||
|
||||
export type VlcPlayerViewProps = {
|
||||
name: string;
|
||||
source: string;
|
||||
};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { requireNativeViewManager } from 'expo-modules-core';
|
||||
import * as React from 'react';
|
||||
import { requireNativeViewManager } from "expo-modules-core";
|
||||
import * as React from "react";
|
||||
|
||||
import { VlcPlayerViewProps } from './VlcPlayer.types';
|
||||
import { VlcPlayerViewProps } from "./VlcPlayer.types";
|
||||
|
||||
const NativeView: React.ComponentType<VlcPlayerViewProps> =
|
||||
requireNativeViewManager('VlcPlayer');
|
||||
requireNativeViewManager("VlcPlayer");
|
||||
|
||||
export default function VlcPlayerView(props: VlcPlayerViewProps) {
|
||||
return <NativeView {...props} />;
|
||||
|
||||
Reference in New Issue
Block a user