Line data Source code
1 1 : <template lang="pug"> 2 34 : Card.x-camera-control(ref='card') 3 34 : template(#info="c" v-if='showControls') 4 34 : p 5 34 : | This is a live camera stream card. 6 : template(v-if='ptz') 7 : hr 8 : strong Pan/Tilt/Zoom control 9 : p 10 : | Some cameras offer Pan/Tilt/Zoom (PTZ) control, when available the #[i.fa.fa-cog] 11 : | button appears. 12 : 13 : p 14 0 : | To control the camera the associated card must be #[span.border-secondary.border.px-1 focused], by clicking on it 15 : | (a light halo and border is displayed around the card). 16 : 17 : p 18 : | PTZ control is achieved using the mouse #[i.fa.fa-mouse], clicking on the image to 19 : | pan and tilt and using the mouse-wheel to zoom. #[br] 20 : | a finer grained zoom is available by holding #[kbd Ctrl] whilst using the mouse-wheel. 21 : 22 : p 23 : | An advanced mode is available by pressing the #[i.fa.fa-cog(title='advanced')] button, it allows 24 : | direct control over the PTZ settings (focus, iris ...). 25 : 26 : p 27 : | The PTZ camera can be reset using the #[i.fa.fa-home(title='home')] button. 28 : 29 : hr 30 : strong Pause and Screenshots 31 : p 32 : | Video streams can be paused using the #[i.fa.fa-pause(title='pause')] button.#[br] 33 : | When triggering the pause a fixed image with maximum resolution the camera can offer 34 : | is displayed and can be downloaded using the #[i.fa.fa-download(title='download')] icon. 35 : 36 : template(#default) 37 : li.p-0.flex-grow-1.d-flex.h-100(key='cam' @wheel='onWheel($event)' @mousedown='onMouseDown()') 38 : BaseAnimationGroup.align-content-center.d-flex.flex-grow-1 39 : img.x-screenshot.m-auto(v-if='paused && screenshot' key='screenshot' :src='screenshot' alt='Screenshot failed') 40 : CameraCard.flex-grow-1(ref='cam' key='cam' v-show='!(paused && screenshot)' 41 : @click.native='moveToPointer($event)' @connected='showControls = $event' 42 : :showFps='true' :useWS='true' :title='camera' :description='description' 43 : :src='$makeUri($butils.currentUrl(), `/cameras/${group}/${camera}?closeOnError=false`).href()') 44 : template(#card-footer) 45 : li(v-if='advanced && canControl && showControls' key='advanced') 46 : .d-flex(v-if='ptz && position && limits') 47 : .row 48 : .col-12.d-flex.align-items-center 49 : span(style='min-width: 5em;') Pan 50 : input.w-100.x.ptz-slider.custom-range(ref='pan' :disabled='refreshing' type='range' 51 : :title='`Pan ${position.pan}`' 52 : :min='limits.MinPan' :max='limits.MaxPan' 53 : @change='move({ pan: Number($event.target.value) }, true)') 54 : .col-12.d-flex.align-items-center 55 : span(style='min-width: 5em;') Tilt 56 : input.w-100.x.ptz-slider.custom-range(ref='tilt' :disabled='refreshing' type='range' 57 : :title='`Tilt ${position.tilt}`' 58 : :min='limits.MinTilt' :max='limits.MaxTilt' 59 : @change='move({ tilt: Number($event.target.value) }, true)') 60 : .col-12.d-flex.align-items-center 61 : span(style='min-width: 5em;') Zoom 62 : input.w-100.x.ptz-slider.custom-range(ref='zoom' :disabled='refreshing' :value='position.zoom' type='range' 63 : :title='`Zoom ${position.zoom}`' 64 : :min='limits.MinZoom' :max='limits.MaxZoom' 65 : @change='move({ zoom: Number($event.target.value) }, true)') 66 : .col-12.d-flex.align-items-center 67 : span(style='min-width: 5em;') Brightness 68 : input.w-100.x.ptz-slider.custom-range(ref='brightness' :disabled='refreshing' :value='position.brightness' type='range' 69 : :title='`Brightness ${position.brightness}`' 70 : :min='limits.MinBrightness' :max='limits.MaxBrightness' 71 : @change='move({ brightness: Number($event.target.value) }, true)') 72 : .col-12.d-flex.align-items-center 73 : span(style='min-width: 5em;') Focus 74 : input.w-100.x.ptz-slider.custom-range(ref='focus' :disabled='refreshing || position.autofocus' :value='position.focus' type='range' 75 : :title='`Focus ${position.focus}`' 76 : :min='limits.MinFocus' :max='limits.MaxFocus' 77 : @change='move({ focus: Number($event.target.value) }, true)') 78 : BaseToggle.d-flex(ref='autofocus' :disabled='refreshing' :inEdit='true' @click.native.prevent='toggleCtrl("autofocus")' title='AutoFocus') 79 : .col-12.d-flex.align-items-center 80 : span(style='min-width: 5em;') Iris 81 : input.w-100.x.ptz-slider.custom-range(ref='iris' :disabled='refreshing || position.autoiris' :value='position.iris' type='range' 82 : :title='`Iris ${position.iris}`' 83 : :min='limits.MinIris' :max='limits.MaxIris' 84 : @change='move({ iris: Number($event.target.value) }, true)') 85 : BaseToggle.d-flex(ref='autoiris' :disabled='refreshing' :inEdit='true' @click.native.prevent='toggleCtrl("autoiris")' title='AutoIris') 86 : button.btn.btn-sm.btn-light.ml-2(:disabled='refreshing' @click='refreshAdvanced()') 87 : i.fa.fa-sync-alt 88 : template(#footer-bar="") 89 : BaseAnimationGroup.x-controls.d-flex.justify-content-center(v-if='showControls') 90 : .col-2(v-if='!(paused && screenshot) && ptz && canControl' key='home' title='home') 91 : button.btn.btn-sm.btn-light.w-100.h-100(@click='move({ tilt: 0, pan: 0, zoom: 0, autofocus: true, autoiris: true }, true)') 92 : i.fa.fa-home 93 : .col-2(v-if='paused && screenshot' key='download') 94 : a.btn.btn-sm.btn-light.w-100.h-100(:href='screenshot' :download='screenshotName' title='download') 95 : i.fa.fa-download 96 : .col-2(v-if='ptz && canControl' key='advanced') 97 : button.btn.btn-sm.w-100.h-100(:class='advanced ? "btn-dark" : "btn-light"' @click='toggleAdvanced()' title='advanced control') 98 : i.fa.fa-cog 99 : .col-2(key='pause') 100 : button.btn.btn-sm.w-100.h-100(:class='paused ? "btn-dark" : "btn-light"' @click='togglePause()' title='pause') 101 35 : i.fa.fa-pause 102 : 103 : </template> 104 : <script src='./CameraControl.vue.js' /> 105 : <style lang='scss'> 106 : .x-screenshot { 107 : min-height: 10em; 108 : } 109 0 : .x-camera-control { 110 : .x-screenshot { 111 : max-width: 100%; 112 0 : max-height: 100%; 113 : height: 100%; 114 : width: auto; 115 : object-fit: contain; 116 : } 117 : } 118 : </style>