이 페이지는 아직 번역되지 않았습니다. 영어 원문 보기

API

Video

nsh exports Video: a video player built on the platform’s player (AVPlayer on iOS and Mac Catalyst, MediaPlayer on Android). Playback is controlled with props, so pausing is a signal away.

import { Video, type VideoProps } from "nsh";

See Web view and video for the guide and <Video> for its props.

#Video

const Video: (props: VideoProps) => JSX.Element;

interface VideoProps extends Omit<ViewProps, "children">, VideoHostProps {
  src: string;
}
import { mount, signal, Text, Video, type VideoRef, View } from "nsh";

function Player() {
  const paused = signal(true);
  const time = signal("");
  let video!: VideoRef;
  return (
    <View style={{ flex: 1, padding: 16, gap: 12 }}>
      <Video
        ref={video}
        src="https://example.com/clip.mp4"
        paused={paused()}
        muted
        repeat
        class="object-cover"
        style={{ height: 220, borderRadius: 8, overflow: "hidden", backgroundColor: "#000" }}
        onProgress={(e) => time.set(`${e.currentTime.toFixed(1)} / ${e.duration.toFixed(1)} s`)}
      />
      <View style={{ flexDirection: "row", gap: 16 }}>
        <Text onPress={() => paused.update((p) => !p)}>{paused() ? "Play" : "Pause"}</Text>
        <Text onPress={() => video.seek(0)}>Restart</Text>
        <Text>{time()}</Text>
      </View>
    </View>
  );
}

mount(Player);

#Props

Video takes the view props (style, classes, layout, accessibility, ref; no children), plus:

PropTypeDefaultDescription
srcstring(required)The video’s URL.
pausedbooleanfalsePlayback is paused.
mutedbooleanfalseNo sound.
volumenumber10..1.
ratenumber1The playback speed.
repeatbooleanfalsePlays again from the start at the end.
controlsbooleanfalseShows the platform’s playback controls.
objectFit (style), object-* classes"cover" | "contain" | "fill" | "none" | "scale-down""contain"How the video fits its box, as CSS’s object-fit (class="object-cover").
progressUpdateIntervalnumber250Milliseconds between onProgress events.
audioSession"default" | "playback" | "mixWithOthers""default"What the sound does to the rest of the device’s audio: see Sound and other apps.

#Sound and other apps

A video’s sound follows the app’s audio settings, which by default are the platform’s for video: on iOS the device’s silent mode silences it. An app that plays speech, as an audiobook or a language course does, sets audioSession:

audioSessionIn silent modeOther apps’ audio while it plays
"default"the app’s audio settings decidethe app’s audio settings decide
"playback"sound playspauses, and plays again once the video pauses, ends or goes
"mixWithOthers"sound playskeeps playing

The setting takes effect while the video plays. On iOS, the first such video to play sets AVAudioSession to the playback category in the spokenAudio mode (mixing with other apps’ audio for "mixWithOthers"), and once none plays the session returns to what it was and the apps it paused may play again; "default" leaves the session as the app, or the app embedding NSH, set it. On Android the player’s sound is marked as speech, and a "playback" video holds audio focus while it plays: it pauses when another app takes the focus (a call, a navigation prompt) and plays on when it comes back. Changing audioSession on Android opens the source again. The desktops and the web play the sound as they play any video.

<Video src="asset:/greeting.m4a" audioSession="playback" />

#Events

EventPayloadWhen
onLoadStartThe video starts loading.
onLoad{ duration: number; size: PixelSize }It is ready to play: its length in seconds and its size in pixels.
onProgress{ currentTime: number; duration: number }While playing, every progressUpdateInterval ms. Seconds.
onBuffer{ isBuffering: boolean }Playback waits for data, or resumes.
onEndPlayback reached the end.
onError{ message: string }The video could not be loaded or played.

#Ref methods

MethodDescription
seek(seconds)Jumps to seconds.
const aspect = signal(16 / 9);

<Video src={url} onLoad={(e) => aspect.set(e.size.width / e.size.height)} style={{ width: "100%", aspectRatio: aspect() }} />;

#Capabilities

When your app declares capabilities in nsh.json, remote video sources must be allowed under network, like fetch; a refused source shows nothing. See Sandbox and capabilities.