ReviewOS

craft-native/craft

feat(native): no Video primitive, so any screen that plays video stays in the WebView

#336
Closed glennmichael123 opened this 9 days ago · {{ comments.length }} {{ comments.length === 1 ? 'comment' : 'comments' }}
9 days ago

The gap

The native host has no Video primitive. CraftNativeScreen.swift switches on ActivityIndicator, FlatList, G, Icon, Image, Modal, Picker, ScrollView, Slider, Svg, SvgText, Switch, Text, TextInput — there is no video view, and the same is true of the Android host.

The capability flags enableVideoRecording and enableAudioRecording exist, so the gap is specifically playback, not capture.

What it blocks

A screen that plays video cannot be a native screen, so it stays in the WebView even when everything else about it is expressible natively.

In HQ.training this is the workout player — resources/views/m/workout/[id].stx:

<video :if="exercisePlay.kind === 'file'" x-src="exercisePlay.url"
       @loadedmetadata="playDemonstration($event)"
       autoplay controls playsinline preload="metadata">

An exercise demonstration plays when its sheet opens. The videos are mirrored onto our own server and served over HTTP range requests, so this is ordinary file playback, not a third-party embed.

Four other screens use <video> the same way: the store product page, the purchased-library player, the coach exercise bank, and purchases.

What would be enough

A Video node mapping to AVPlayerViewController (or an AVPlayerLayer in a plain view) on iOS and ExoPlayer/VideoView on Android, with the props that <video> already uses here:

  • src
  • controls
  • autoplay
  • playsinline — matters on iOS, where video otherwise goes fullscreen
  • preload
  • a loadedmetadata-equivalent event, which is what the player uses to seek to the demonstration's start

Range-request support is the thing most likely to be fiddly: iOS is particular about it, and it is what changes when a file is served from our own origin rather than a CDN.

Not part of this

Third-party embeds (YouTube, Vimeo) are out of scope — those need a web view by nature, and a native screen that needs one is a screen that should stay web for now.

9 days ago

Resolved on main by ebc06d7 (feat(native): add cross-platform video primitive). Native Video is available on iOS and Android, with playback/source/lifecycle coverage in the renderer contract and maintained fixtures.

Sign in to comment on this issue.