33//
44// Media input widget
55//
6- // In future this will be really simple to do when
7- // the HTML5 input "image capture" input element is actually deployed
8- // In the meantime (2017-01) this seems to be the state of the art.
96//
107// Workflow:
118// The HTML5 functionality (on mobille) is to prompt for either
1411// or access cemra roll (etc) OR to access solid cloud storage of favorite photo almbums.
1512// (Especially latest taken ones)
1613//
17- /* global alert */
14+ /* global alert confirm */
15+
16+ /** @module mediaCapture */
17+
1818var $rdf = require ( 'rdflib' )
1919var media = module . exports = { }
2020
@@ -30,10 +30,107 @@ var UI = {
3030 widgets : require ( './widgets' )
3131}
3232
33+ /** A control to capture a picture using camera
34+ * @param {Docuemnt } dom - The Document object
35+ * @param {IndexedForumla } store - The quadstore to store data in
36+ * @param {NamedNode } destination - NN of the image file to be created
37+ * @param {function } doneCallback - Called when a picture has been taken
38+ */
39+ function cameraCaptureControl ( dom , store , destination , doneCallback ) {
40+ const div = dom . createElement ( 'div' )
41+ const player = div . appendChild ( dom . createElement ( 'video' ) )
42+ const controlStyle = 'border-radius: 0.5em; margin: 0.8em; width: 320; height:240;'
43+ const contentType = 'image/png'
44+ // player.setAttribute('controls', '1')
45+ player . setAttribute ( 'autoplay' , '1' )
46+ const button = div . appendChild ( dom . createElement ( 'button' ) )
47+ button . textContent = 'Capture'
48+ player . setAttribute ( 'style' , controlStyle )
49+ var canvas
50+
51+ const constraints = {
52+ video : true
53+ }
54+
55+ function grabCanvas ( ) {
56+ // Draw the video frame to the canvas.
57+ canvas = dom . createElement ( 'canvas' )
58+ canvas . setAttribute ( 'width' , '320' )
59+ canvas . setAttribute ( 'height' , '240' )
60+ canvas . setAttribute ( 'style' , controlStyle )
61+ player . parentNode . appendChild ( canvas )
62+
63+ const context = canvas . getContext ( '2d' )
64+ context . drawImage ( player , 0 , 0 , canvas . width , canvas . height )
65+
66+ // Stop all video streams.
67+ player . srcObject . getVideoTracks ( ) . forEach ( track => track . stop ( ) )
68+ player . parentNode . removeChild ( player )
69+
70+ canvas . toBlob ( blob => {
71+ let msg = `got blob type ${ blob . type } size ${ blob . size } `
72+ console . log ( msg )
73+ saveBlob ( blob , destination )
74+ alert ( msg )
75+ } , contentType ) // toBlob
76+ }
77+
78+ function saveBlob ( blob , destination ) {
79+ let contentType = blob . type
80+ if ( ! confirm ( 'Save picture to ' + destination + ' ?' ) ) return
81+ console . log ( 'Putting ' + blob . size + ' bytes of ' + contentType + ' to ' + destination )
82+ store . fetcher . webOperation ( 'PUT' , destination . uri , { data : blob , contentType : contentType } ) . then ( resp => {
83+ console . log ( 'ok saved ' + destination )
84+ alert ( 'saved ok: ' + destination )
85+ } , err => {
86+ alert ( err )
87+ } )
88+ }
89+
90+ button . addEventListener ( 'click' , grabCanvas )
91+
92+ // Attach the video stream to the video element and autoplay.
93+ navigator . mediaDevices . getUserMedia ( constraints )
94+ . then ( ( stream ) => {
95+ player . srcObject = stream
96+ } )
97+ return div
98+ }
99+
100+ /** A button to capture a picture using camera
101+ * @param {Docuemnt } dom - The Document object
102+ * @param {IndexedForumla } store - The quadstore to store data in
103+ * @param {NamedNode } destination - NN of the image file to be created
104+ * @returns {DomElement } - A div element with the buton in it
105+ *
106+ * This expacts the buttton to a large control when it is pressed
107+ */
108+ function cameraButton ( dom , store , destination ) {
109+ const div = dom . createElement ( 'div' )
110+ const but = UI . widgets . button ( dom , UI . icons . iconBase + 'noun_383448.svg' , 'Take picture' )
111+ var control
112+ function restoreButton ( ) {
113+ div . removeChild ( control )
114+ div . appendChild ( but )
115+ }
116+ div . appendChild ( but )
117+ but . addEventListener ( 'click' , event => {
118+ div . removeChild ( but )
119+ control = control || cameraCaptureControl ( dom , store , destination , restoreButton )
120+ div . appendChild ( control )
121+ } )
122+ return div
123+ }
124+
125+ media . cameraButton = cameraButton
126+ media . cameraCaptureControl = cameraCaptureControl
127+
128+ /// /////////////////////////////////////// OLD BROKEN
129+
33130// Put up a video stream and take a picture
34131// In: context.div, dom
35132
36- UI . media . camera = function ( context , gotBlob ) {
133+ UI . media . cameraOLD = function ( context , gotBlob ) {
37134 function takeSnapshot ( ) {
38135 var dom = context . dom
39136 var img = dom . createElement ( 'img' )
0 commit comments