when the server stop the stream transfering?

yangjun1222
Posts: 2
Joined: Thu Mar 23, 2023 2:58 am

when the server stop the stream transfering?

Postby yangjun1222 » Thu Mar 23, 2023 3:30 am

HI, I am reading the web cam server example project. I write a simple c program using vs code.
  1. #include  "camera_index.h"
  2. int  main()
  3. {
  4. FILE *file = fopen("index1.bin", "w");
  5. // Check if the file is opened successfully
  6. if (file == NULL)
  7. {
  8. printf("Error opening file\\n");
  9. return  1;
  10. }
  11. // Write each element of the array into the file
  12. for (int  i = 0; i < 4408; i++)
  13. {
  14. fputc(index_ov3660_html_gz[i], file);
  15. // Close the file
  16. fclose(file);
  17. return  0;
  18. }
then gzip -d index1.bin -c > index1.html, I get the html file (following ignore the css, html part of the file )
  1. document.addEventListener('DOMContentLoaded', function (event) {
  2.   var baseHost = document.location.origin
  3.   var streamUrl = baseHost + ':81'
  4.  
  5.   const hide = el => {
  6.     el.classList.add('hidden')
  7.   }
  8.   const show = el => {
  9.     el.classList.remove('hidden')
  10.   }
  11.  
  12.   const disable = el => {
  13.     el.classList.add('disabled')
  14.     el.disabled = true
  15.   }
  16.  
  17.   const enable = el => {
  18.     el.classList.remove('disabled')
  19.     el.disabled = false
  20.   }
  21.  
  22.   const updateValue = (el, value, updateRemote) => {
  23.     updateRemote = updateRemote == null ? true : updateRemote
  24.     let initialValue
  25.     if (el.type === 'checkbox') {
  26.       initialValue = el.checked
  27.       value = !!value
  28.       el.checked = value
  29.     } else {
  30.       initialValue = el.value
  31.       el.value = value
  32.     }
  33.  
  34.     if (updateRemote && initialValue !== value) {
  35.       updateConfig(el);
  36.     } else if(!updateRemote){
  37.       if(el.id === "aec"){
  38.         value ? hide(exposure) : show(exposure)
  39.       } else if(el.id === "agc"){
  40.         if (value) {
  41.           show(gainCeiling)
  42.           hide(agcGain)
  43.         } else {
  44.           hide(gainCeiling)
  45.           show(agcGain)
  46.         }
  47.       } else if(el.id === "awb_gain"){
  48.         value ? show(wb) : hide(wb)
  49.       } else if(el.id === "face_recognize"){
  50.         value ? enable(enrollButton) : disable(enrollButton)
  51.       }
  52.     }
  53.   }
  54.  
  55.   function updateConfig (el) {
  56.     let value
  57.     switch (el.type) {
  58.       case 'checkbox':
  59.         value = el.checked ? 1 : 0
  60.         break
  61.       case 'range':
  62.       case 'select-one':
  63.         value = el.value
  64.         break
  65.       case 'button':
  66.       case 'submit':
  67.         value = '1'
  68.         break
  69.       default:
  70.         return
  71.     }
  72.  
  73.     const query = `${baseHost}/control?var=${el.id}&val=${value}`
  74.  
  75.     fetch(query)
  76.       .then(response => {
  77.         console.log(`request to ${query} finished, status: ${response.status}`)
  78.       })
  79.   }
  80.  
  81.   document
  82.     .querySelectorAll('.close')
  83.     .forEach(el => {
  84.       el.onclick = () => {
  85.         hide(el.parentNode)
  86.       }
  87.     })
  88.  
  89.   // read initial values
  90.   fetch(`${baseHost}/status`)
  91.     .then(function (response) {
  92.       return response.json()
  93.     })
  94.     .then(function (state) {
  95.       document
  96.         .querySelectorAll('.default-action')
  97.         .forEach(el => {
  98.           updateValue(el, state[el.id], false)
  99.         })
  100.     })
  101.  
  102.   const view = document.getElementById('stream')
  103.   const viewContainer = document.getElementById('stream-container')
  104.   const stillButton = document.getElementById('get-still')
  105.   const streamButton = document.getElementById('toggle-stream')
  106.   const enrollButton = document.getElementById('face_enroll')
  107.   const closeButton = document.getElementById('close-stream')
  108.  
  109.   const stopStream = () => {
  110.     window.stop();
  111.     streamButton.innerHTML = 'Start Stream'
  112.   }
  113.  
  114.   const startStream = () => {
  115.     view.src = `${streamUrl}/stream`
  116.     show(viewContainer)
  117.     streamButton.innerHTML = 'Stop Stream'
  118.   }
  119.  
  120.   // Attach actions to buttons
  121.   stillButton.onclick = () => {
  122.     stopStream()
  123.     view.src = `${baseHost}/capture?_cb=${Date.now()}`
  124.     show(viewContainer)
  125.   }
  126.  
  127.   closeButton.onclick = () => {
  128.     stopStream()
  129.     hide(viewContainer)
  130.   }
  131.  
  132.   streamButton.onclick = () => {
  133.     const streamEnabled = streamButton.innerHTML === 'Stop Stream'
  134.     if (streamEnabled) {
  135.       stopStream()
  136.     } else {
  137.       startStream()
  138.     }
  139.   }
  140.  
  141.   enrollButton.onclick = () => {
  142.     updateConfig(enrollButton)
  143.   }
  144.  
  145.   // Attach default on change action
  146.   document
  147.     .querySelectorAll('.default-action')
  148.     .forEach(el => {
  149.       el.onchange = () => updateConfig(el)
  150.     })
  151.  
  152.   // Custom actions
  153.   // Gain
  154.   const agc = document.getElementById('agc')
  155.   const agcGain = document.getElementById('agc_gain-group')
  156.   const gainCeiling = document.getElementById('gainceiling-group')
  157.   agc.onchange = () => {
  158.     updateConfig(agc)
  159.     if (agc.checked) {
  160.       show(gainCeiling)
  161.       hide(agcGain)
  162.     } else {
  163.       hide(gainCeiling)
  164.       show(agcGain)
  165.     }
  166.   }
  167.  
  168.   // Exposure
  169.   const aec = document.getElementById('aec')
  170.   const exposure = document.getElementById('aec_value-group')
  171.   aec.onchange = () => {
  172.     updateConfig(aec)
  173.     aec.checked ? hide(exposure) : show(exposure)
  174.   }
  175.  
  176.   // AWB
  177.   const awb = document.getElementById('awb_gain')
  178.   const wb = document.getElementById('wb_mode-group')
  179.   awb.onchange = () => {
  180.     updateConfig(awb)
  181.     awb.checked ? show(wb) : hide(wb)
  182.   }
  183.  
  184.   // Detection and framesize
  185.   const detect = document.getElementById('face_detect')
  186.   const recognize = document.getElementById('face_recognize')
  187.   const framesize = document.getElementById('framesize')
  188.  
  189.   framesize.onchange = () => {
  190.     updateConfig(framesize)
  191.     if (framesize.value > 5) {
  192.       updateValue(detect, false)
  193.       updateValue(recognize, false)
  194.     }
  195.   }
  196.  
  197.   detect.onchange = () => {
  198.     if (framesize.value > 5) {
  199.       alert("Please select CIF or lower resolution before enabling this feature!");
  200.       updateValue(detect, false)
  201.       return;
  202.     }
  203.     updateConfig(detect)
  204.     if (!detect.checked) {
  205.       disable(enrollButton)
  206.       updateValue(recognize, false)
  207.     }
  208.   }
  209.  
  210.   recognize.onchange = () => {
  211.     if (framesize.value > 5) {
  212.       alert("Please select CIF or lower resolution before enabling this feature!");
  213.       updateValue(recognize, false)
  214.       return;
  215.     }
  216.     updateConfig(recognize)
  217.     if (recognize.checked) {
  218.       enable(enrollButton)
  219.       updateValue(detect, true)
  220.     } else {
  221.       disable(enrollButton)
  222.     }
  223.   }
  224. })
  225.  
then I read the app_httpd.cpp and the index.html I got. I understand how the stream server start, but then it enters a dead loop. the browser stop the stream through : window.stop(), how does the server receive this message?I can not find a break in this dead loop which is caused by a request from browser?
  1. static esp_err_t stream_handler(httpd_req_t *req)
  2.  while(true){.......................}

noweare
Posts: 50
Joined: Tue Jul 02, 2019 11:35 am

Re: when the server stop the stream transfering?

Postby noweare » Sat Mar 25, 2023 4:26 pm

Good question.

No doubt that the javascript and the camera application is very advanced and not easily understood.
The furthest I could get was "stop stream" button on the browser is pressed which runs the stopStream function which executes window.stop command. window.stop command discontinues loading the stream-container and hides it from view. This causes
stream handler code on the esp32 to return a "send response error" while trying to send a chunk.

I am trying to learn advanced javascript/html/css using this application so I can use it in my own projects. Learning HTML and CSS
is not that difficult but integrating javascript with esp32 code is more of a challenge.

I know this answer is not complete and could be much better answered by an experienced programmer.

Good luck

Who is online

Users browsing this forum: No registered users and 62 guests