9191import Vue from ' vue'
9292
9393import SelfHealthTest from ' @/components/health/SelfHealthTest.vue'
94+ import VideoThumbnail from ' @/components/video-manager/VideoThumbnail.vue'
9495import GenericViewer from ' @/components/vehiclesetup/viewers/GenericViewer.vue'
96+ import { OneMoreTime } from ' @/one-more-time'
9597import helper from ' @/store/helper'
9698import mavlink from ' @/store/mavlink'
99+ import video from ' @/store/video'
97100import { InternetConnectionState } from ' @/types/helper'
101+ import { StreamStatus } from ' @/types/video'
98102import mavlink_store_get from ' @/utils/mavlink'
99103import CPUUsage from ' @/widgets/CpuPie.vue'
100104import Networking from ' @/widgets/Networking.vue'
@@ -123,9 +127,16 @@ export default Vue.extend({
123127 data : () => ({
124128 windowHeight: window .innerHeight ,
125129 windowWidth: window .innerWidth ,
130+ fetch_streams_task: new OneMoreTime ({ delay: 10000 , disposeWith: this }),
126131 }),
127132 computed: {
128133 apps(): AppItem [] {
134+ return [
135+ ... this .baseApps ,
136+ ... this .videoStreamWidgets ,
137+ ]
138+ },
139+ baseApps(): AppItem [] {
129140 return [
130141 {
131142 icon: ' mdi-view-dashboard' ,
@@ -183,6 +194,41 @@ export default Vue.extend({
183194 },
184195 ]
185196 },
197+ videoStreamWidgets(): AppItem [] {
198+ return this .video_streams .reduce <AppItem []>((widgets , stream ) => {
199+ const source = this .streamSource (stream )
200+ if (! source ) {
201+ return widgets
202+ }
203+
204+ widgets .push ({
205+ icon: stream .running ? ' mdi-video-check' : ' mdi-video-off' ,
206+ title: stream .video_and_stream .name ,
207+ route: ' /vehicle/video-manager' ,
208+ component: VideoThumbnail ,
209+ size: {
210+ w: 0.4 ,
211+ h: 1.2 ,
212+ },
213+ props: {
214+ source ,
215+ register: stream .running ,
216+ width: ' 100%' ,
217+ height: ' auto' ,
218+ },
219+ style: {
220+ display: ' flex' ,
221+ alignItems: ' center' ,
222+ justifyContent: ' center' ,
223+ },
224+ })
225+
226+ return widgets
227+ }, [])
228+ },
229+ video_streams(): StreamStatus [] {
230+ return video .available_streams
231+ },
186232 has_internet(): boolean {
187233 return helper .has_internet !== InternetConnectionState .OFFLINE
188234 },
@@ -197,6 +243,7 @@ export default Vue.extend({
197243 window .addEventListener (' resize' , this .handleResize )
198244 this .handleResize ()
199245 mavlink .setMessageRefreshRate ({ messageName: ' ATTITUDE' , refreshRate: 10 })
246+ this .fetch_streams_task .setAction (video .fetchStreams )
200247 },
201248 beforeDestroy() {
202249 window .removeEventListener (' resize' , this .handleResize )
@@ -206,6 +253,22 @@ export default Vue.extend({
206253 this .windowHeight = window .innerHeight
207254 this .windowWidth = window .innerWidth
208255 },
256+ streamSource(stream : StreamStatus ): string | undefined {
257+ const source = stream .video_and_stream .video_source
258+ if (' Local' in source ) {
259+ return source .Local .device_path
260+ }
261+ if (' Redirect' in source ) {
262+ return source .Redirect .source .Redirect
263+ }
264+ if (' Onvif' in source ) {
265+ return source .Onvif .source .Onvif
266+ }
267+ if (' Gst' in source ) {
268+ return source .Gst .source .Fake
269+ }
270+ return undefined
271+ },
209272 },
210273})
211274 </script >
0 commit comments