Autor Zpráva
hansmol
Profil
Zdravím vás,
mohl bych vás požádat o radu?
Stručně řečeno:
Mám zařízení, na němž běží program pomocí něhož snímám obraz z kamerky (OpenCV) tento obraz převádím do JPEG formy a z dané struktury, kam se tato JPEG forma uloží si vyčítám data do textového bufferu. Program krom načítání obrazu obsahuje serverovou část (jako socket(), bind(), listen(), accept(), recv() a send(). Zmíněný textový buffer opatřím HTTP hlavičkou HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\nContent-length: %d\r\n\r\nBINARY DATA a pomocí příkazu send() ho odesílám klientovy na stejné síti, který v prohlížeči zadal http://IP:PORT. Pro načtení nového snímku nyní musím kliknout na refresh nebo ho vyvolat přes klávesu F5.

Rád bych aby se stránka obnovovala sama. Zatím jsem zkoušel v html tyto příkazy
<meta http-equiv="Refresh" content="1">
<img src="./server-frame.jpeg">

Ovšem to vyžadovalo snímek na disku (nevhodné, snímek je v paměti RAM) a minimální obnovovací frekvence je 1 Hz (pomalé, lepší by bylo více Hz).

Na toto mi byl mi doporučen JavaScript, ale tento jazyk vidím poprvé, stejně tak jako další "stránkové jazyky" (html,php)

A druhá otázka.
Na tom zařízení mám *.txt soubor, který bych rád přes síť přenesl a pomocí prohlížeče uložil.
Zde mi bylo doporučeno použít php s download buttonem. Tady kliknout na "čudlík" což by způsobilo stažení souboru.

Mohl by mi prosím někdo poradit jak tyto cíle co nejsnáze či nejlépe provést?
Jsou doporučení správná, či je lepší řešit to jinak?
Lze poslat obrázek jako BINARNI DATA pokud budu zasílat jinou hlavičku než s Content-Type: image/jpeg ?
Mám teď také trochu zmatek jak tyto části skloubit.

Za každou radu, odkaz, pomoc budu opravdu rád.
Děkuji.
Str4wberry
Profil
Zdá se mi, že stačí použít 1000ms setInterval a nastavovat src obrázku s přidáním náhodného smetí pro jistotu, aby se obrázek nezobrazoval z cache prohlížeče.

Živá ukázka
hansmol
Profil
Str4wberry:
Zdravím, děkuji za odpověď.

Našel jsem zde něco podobného viz.

<html>
  <head>
    <title>Test--html</title>
  </head>
  <body>
    <img src='D:\obr.jpeg' id="mujObr" >
    <script type="text/javascript">
      window.onload = function() {
      window.setInterval(function() {
      
       document.getElementById('mujObr').src = 'D:\obr.jpeg?' + new Date().getTime(); 
       }, 5000);
      }
    </script>
  </body>
</html>

Pokud tento kód vložím do poznámkového bloku a uložím to jako *.html a následně to nechám zobrazit v prohlížeči, vše funguje jak má.

Problém ovšem nastává, když si tento obsah html pošlu přes server viz.
Odpověď
char *response = 
  "HTTP/1.1 200 OK\r\n"
  "Content-Type: text/html\r\n"
  "Content-length: 288\r\n"
  "\r\n"
  "<html>"
  "<head>"
  "<title>Test--html</title>"
  "</head>"
  "<body>"
  "<img src='D:\\obr.jpeg' id=\"mujObr\">"
  "<script type=\"text/javascript\">"
  "window.onload = function() {"
  "window.setInterval(function() {"
  "document.getElementById('mujObr').src = 'D:\\obr.jpeg?' + new Date().getTime(); }, 5000); }"
  "</script>"
  "</body>"
  "</html>"
  "\0";

Odeslání
send(new_fd, response, 353);

Po těchto krocích se sice správně načte název stránky (nahoře v prohlížeči) ale zobrazuje se prázdné (bílé) okno.
Str4wberry
Profil
Myslel jsem to spíš tak, že uvedený kód s časovačem může běžet mimo ten server, ale ze serveru jen každou vteřinu načítat aktuální obrázek.
_es
Profil
hansmol:
Problém ovšem nastává, když si tento obsah html pošlu přes server
Cudzí návštevník samozrejme nevidí tvoj súbor D:\\obr.jpeg. Aby to išlo mimo tvojho prehliadača, musel by byť ten obrázok prístupný aj zvonka. Alebo ak ide o prístup z tvojho prehliadača cez http://localhost, tak musí byť aj obrázok dostupný cez protokol HTTP.
hansmol
Profil
Str4wberry:
Myslel jsem to spíš tak, že uvedený kód s časovačem může běžet mimo ten server, ale ze serveru jen každou vteřinu načítat aktuální obrázek.

Ano tento záměr (až na kratší dobu) chci také dosáhnout.

Problém je jak dostat ten HTML soubor s tím JavaScriptovým kódem do cílového zařízení a tam ho spustit. Myslel jsem, že pokud ten kód odešlu tak jak jsem uvedl, pak se kód spustí a bude si ten obrázek vyčítat sám.


_es:
Cudzí návštevník samozrejme nevidí tvoj súbor D:\\obr.jpeg. Aby to išlo mimo tvojho prehliadača, musel by byť ten obrázok prístupný aj zvonka.

Jooo to máte pravdu, teď mi to došlo, safra.
Ten script se tam sice pošle a spustí, ale na tom cílovém zařízení to bude hledat ten JPEG na uvedeném umístění, kde samozřejmě nebude.

Alebo ak ide o prístup z tvojho prehliadača cez http://localhost, tak musí byť aj obrázok dostupný cez protokol HTTP.

To myslíte tak, že bych měl zasílat ten obrázek přes HTTP? To už jsem hledal a našel jsem že se to dělá pomocí Data-URI a tam musí být zakódován pomocí base64. Nebo to myslíte ještě jinak?

Oběma děkuji za pomoc a rady :)
_es
Profil
hansmol:
To myslíte tak, že bych měl zasílat ten obrázek přes HTTP?
Áno:
<img src="http://adresaObrázka">
hansmol
Profil
_es:
Mohl byste mi prosím prozradit jak? Zkouším zde různé způsoby ale nejsem úspěšný.

JPEG soubor mám na oddílu disku označeném jako D: na systemu windows.
Tedy cesta k souboru v systému je D:\obr.jpeg
IP 192.168.0.4 (či 127.0.0.1)
_es
Profil
hansmol:
No a o čo sa vlastne snažíš?
- Aby mohol hocikto kameru sledovať cez internet?
- - To budeš musieť mať verejnú IP adresu, musí byť na tvojom počítači spustený HTTP server a bude to fungovať, len ak bude tvoj počítač zapnutý.
- Aby si mohol sledovať kameru ty sám?
- - To ti už funguje („Pokud tento kód vložím do poznámkového bloku a uložím to jako *.html a následně to nechám zobrazit v prohlížeči, vše funguje jak má.“), len ak to zobrazuješ cez HTTP server a protokol HTTP, tak aj obrázok musí byť dostupný cez HTTP protokol.
hansmol
Profil
_es:
Snažím se o to, aby se uživateli který bude na stejné síti (wifi), která je vytvářena pomocí malého zařízení s linuxem (Raspberry PI) po spuštění internetového prohlížeče na svém přístroji (notebook, tablet atp) a po zadání IP a PORTu toho RPi, zobrazil snímek z kamery a automaticky se načítal snímek nový.

V současné době mi běží na tom RPi program, který načte snímek, ten také zakóduje do formy JPEG, potom ho vloží textového bufferu, následně ho opatří HTTP hlavičkou a nakonec vytvoří socket() ten připojí k IP a PORTu toho RPi (bind) a naslouchá (listen) na zmíněném portu na Uživatelský požadavek ( uživatel zadá IP:PORT do prohlížeče, stiskne Enter a tím vyšle prohlížeč HTTP zprávu GET), když požadavek přijde dojde k přijetí (accept) a odeslání připravené zprávy (textový buffer kde je HTTP hlavicka + binarni data JPEG snímku).

Pro načtení nového snímku je potřeba kliknout na ikonu pro refresh nebo tuto aktualizaci vyvolat pomocí klávesové zkratky F5.

Pro automatický refresh stránky mi byl doporučen JavaScript. Zkoušel jsem i meta tag uvedený výše, ale tam je minimální obnovování jen 1 za sekundu.

Odesílané data (tedy snímky) mohou být buď v operační paměti ale mohou být i ukládané na disk.

Ten *.html soubor jsem zkoušel pro ověření funkce. Jak tento soubor, tak i obrázek ve formátu JPEG byly na notebooku. Myslel jsem že bude stačit odeslat obsah toho HTML souboru uživateli (do prohlížeče) a on si poté obrázek načte. Ale to zřejmě nepůjde takto snadno.

Opravdu děkuji za pomoc :)
_es
Profil
hansmol [#10]:
No a to celé, čo si popísal v druhom odseku, asi má aj nejakú URL adresu. Ak ju zadáš ako atribút src do obrázku v skripte v [#3], tak to fungovať nebude?
Str4wberry
Profil
Nemůže ten server vracet obsah na více adresách?

Tj. na IP:PORT vrátit HTML stránku, která bude načítat (a refreshovat) IP:PORT/obrazek.jpg?
hansmol
Profil
_es, Str4wberry:

Jste machři :) díky moc.
Poupravil jsem v kódu serverovou část a už to funguje.

Nejdříve se načte snímek z kamery, server vyčká na připojení na adresu IP:PORT. Na tento požadavek zašle server klientovi HTML s JavaScriptem, který způsobí vynucení zaslání požadavku na IP:PORT/obr.jpg. Server tento požadavek přijme, přes podmínku zda se nachází v požadavku "obr.jpeg" rozhodne a když se nachází, tak vloží načtený snímek z kamery do bufferu a ten se odesílá zpět klientovi.

Mám ještě drobné problémy s FPS pokud nastavím window.setInterval na 100 ms (10 FPS) tak to jako video zobrazí pouze prvních pár snímku a zastaví se na jednom z nich. Ale na 290 ms funguje relativně plynule. Ale to zkusím ještě vylepšit na straně komprese JPEG.

---
Mohli byste mi prosím poradit ještě s tím druhým "problémkem".

Potřeboval bych, aby se někde v tom prohlížeči (nejlépe pod tím "videem") zobrazila možnost stáhnout data. Konkrétně by se měl stahovat TXT soubor z toho serveru. Prohlížeč by po kliknutí na stáhnout data měl vyslat zřejmě požadavek na zmíněný soubor, server by jej měl poslat zpět a prohlížeč by ho měl uložit na disk klienta.

Existuje v html + javascriptu takováto možnost?

EDIT: Teď mě napadlo, že ten link/button na stažení souboru asi nebude moci být na stejné stránce jako ta kde se refreshuje ten snímek, že? V tom případě by bylo dobré aby se po úvodním zadání IP:PORT načetla stránka, kde by byl tento stahovací element a samotná aktualizace snímků by se otevřela v novém panelu prohlížeče. Nebo se mýlím ?
_es
Profil
hansmol:
Mám ještě drobné problémy s FPS pokud nastavím window.setInterval na 100 ms (10 FPS) tak to jako video zobrazí pouze prvních pár snímku a zastaví se na jednom z nich.
To pretože je server zahltený požiadavkami, nestíha ich spracovať a okrem toho ich počet ešte stále narastá. Dalo by sa to vyriešiť, aby sa to zobrazovalo v takej frekvencii, čo server vládze, no bez zahltenia servera:
var i = new Image, obrazok = document.getElementById('mujObr'), adresaObrazka = "adresaObrázka?";
i.onload = function(){
  obrazok.src = this.src;
  this.src = adresaObrazka + new Date().getTime();
};
i.src = adresaObrazka + new Date().getTime();
Ďalší pozitívny jav: nebude zobrazovaný čiastočne načítaný obrázok.

Na to sťahovanie súboru by mal stačiť normálny odkaz. Aby sa obsah nezobrazil v prehliadači, mal by mať nejaký neznámy/nezobraziteľný MIME typ, prípadne môžeš dať aj odkaz s target=_blank.
hansmol
Profil
_es:
Omlouvám se za delší nepřítomnost, měl jsem bohužel jiné nečekané starosti.

Wooow ty si machr :) Funguje to naprosto parádně :)
Jen jestli se můžu zeptat, jak to principiálně funguje?

Zatím to chápu tak, že nejdříve v HTML části si zobrazím obrázek viz.
<img src=http://10.0.0.1:8080/obr.jpeg id="mujObr">

Pote v části SCRIPT za:
1. Vytvořím element typu Image, do obrazok nastavím na ten zobrazený obrázek výše, adresaObrazka nastavím na "http://10.0.0.1:8080/obr.jpeg?" (otazník proto aby se ta adresa měnila?)

2. Image element nazvaný "i" počká až se načte celá stránka a poté spustí funkci

3. Funkce nastaví elementu "obrazok" src (zdroj) na src (zdroj) this (který ale ještě neznám ne?)

4. this.src nastavím na http://10.0.0.1:8080/obr.jpeg? + novýčas (aktualizace)

5. Nastavím src (zdroj) elementu image nazvaného "i" na http://10.0.0.1:8080/obr.jpeg? + novýčas (aktualizace)

Chápu to asi zle, že?
Jak je možné nastavovat ve 3 řádku něco, co je nastavené až ve 4 řádku?
Proč je tam aktualizace 2* ?

BTW
Stahování TXT souboru jsem vyrešil následovně:
<span title="Klikněte zde pro stažení GPS logu.">
<button type="submit" onclick="window.open('gps-log.txt')">Stáhnout GPS data!</button></span>

Na serverové straně se s tím vypořádám a po kliknutí v prohlížeči se na 1s otevře nové okno a zahájí se klasické stahování souboru.

Můžu ještě dotaz jak by se dalo zajistit, aby po kliknutí na obrázek se roztáhl přes celou obrazovku - FullScreen - a byla zachována autoaktualizace ?


OPRAVDU JSEM VÁM NESMÍRNĚ VDĚČNÝ ZA POMOC :) :) :)

-------------------------------------------
EDIT: Tak to vypadalo, že to funguje, bohužel však po pár minutách program spadne.
_es
Profil
hansmol:
otazník proto aby se ta adresa měnila?
Aby bolo isté, že sa nezobrazí „stará“ verzia obrázka z cache.

Jak je možné nastavovat ve 3 řádku něco, co je nastavené až ve 4 řádku?
Proč je tam aktualizace 2* ?
Premenná i je len na to, aby sa obrázok načítal do pamäte. Vtedy nastane udalosť onload a premennej obrazok je nastavená adresa už načítaného obrázka.

aby po kliknutí na obrázek se roztáhl přes celou obrazovku - FullScreen
Režim na celú obrazovku sa dá zapnúť v prehliadači. Obrázok sa dá nastaviť ako pozadie: Background-image, alebo obrázku zmeniť atribúty width a height.

bohužel však po pár minutách program spadne.
Skús nejaký iný prehliadač. „Nepadá“ prehliadač v dôsledku zaplnenia pamäte?

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: