TzuHuanTai / PiCamera.js

WebRTC Connection and Video Stream for Raspberry Pi Camera.
https://www.npmjs.com/package/picamera.js
GNU Affero General Public License v3.0
2 stars 2 forks source link

Please include full working HTML example in documentation #7

Closed thomergil closed 2 weeks ago

thomergil commented 2 weeks ago

I'd be curious to see a full HTML page with a working PiCamera.js example. (Of course there is PiCamera Web, but the source HTML is obfuscated and cannot easily be inspected.)

thomergil commented 2 weeks ago

For example,

html-src/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
    <style>
    .video-container {
      border: 2px solid black;
      position: relative;
      width: 100%; /* Full width of column */
      max-width: 1200px; /* Limit width to avoid scaling too large */
      aspect-ratio: 16 / 9; /* Enforces a fixed 16:9 aspect ratio */
      overflow: hidden; /* Prevents video from spilling out */
    }

    /* Fit image in video container */
    .fit-image {
      width: 100%;  /* Full width of container */
      height: 100%; /* Full height of container */
      object-fit: cover; /* Fills the container without distorting */
    }
    </style>
  </head>

  <body>
    <div class="video-container">
      <video id="video" class="fit-image" autoplay playsinline></video>
    </div>
  </body>
</html>

html-src/main.js

import { PiCamera } from 'picamera.js';

document.addEventListener("DOMContentLoaded", function() {
  let videoRef = document.getElementById('video');

  let conn = new PiCamera({
    deviceUid: 'picam-demo',
    mqttHost: `${window.location.hostname}`,
    mqttPath: '/mqtt',
  });
  conn.attach(videoRef);
  conn.connect();
})

webpack.config.js

const path = require('path');                                                                                                                               •
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './html-src/main.js',
  output: {
    filename: 'bundle.[contenthash].js', // Adds a unique hash to the filename
    path: path.resolve(__dirname, 'html'),
    clean: true,                         // Clears outdated files from the output directory
  },
  mode: 'development',
  plugins: [
    new HtmlWebpackPlugin({
      template: './html-src/index.html',
      inject: 'body',
    }),
  ],
  devServer: {
    contentBase: path.join(__dirname, 'html'),
    hot: true, // Enables hot reloading
  },
};

Running

yarn
yarn build

Will generate html/index.html and html/bundle.{contenthash}.js

nginx.conf

pid /home/pi/src/beamtoo/run/nginx.pid;

events {}

http {
  # Map to manage WebSocket upgrade headers
  map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
  }

  # Upstream definition for Mosquitto WebSocket listener
  upstream mosquitto_websocket {
    server localhost:1884;  # Mosquitto WebSocket listener
  }

  # HTTPS server
  server {
    listen 443 ssl;
    access_log /home/pi/src/beamtoo/logs/access.log;
    error_log /home/pi/src/beamtoo/logs/error.log;

    ssl_certificate /home/pi/src/beamtoo/ssl/server.crt;
    ssl_certificate_key /home/pi/src/beamtoo/ssl/server.key;

    location / {
      root /home/pi/src/beamtoo/html/;
      try_files $uri $uri/ =404;
    }

    # Location block for WebSocket proxying to Mosquitto
    location /mqtt {
      proxy_pass http://mosquitto_websocket;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
    }
  }

  # HTTP server
  server {
    listen 8080;
    access_log /home/pi/src/beamtoo/logs/access_http.log;
    error_log /home/pi/src/beamtoo/logs/error_http.log;

    location / {
      root /home/pi/src/beamtoo/html/;
      try_files $uri $uri/ =404;
    }

    # Location block for WebSocket proxying to Mosquitto over HTTP
    location /mqtt {
      proxy_pass http://mosquitto_websocket;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
    }
  }
}

mosquitto.conf

listener 1883 localhost
allow_anonymous true

listener 1884
protocol websockets
allow_anonymous true
TzuHuanTai commented 2 weeks ago

Thank you! I updated a demo index.html, it would be easier to have all in one. You can open and use it directly without compile or so.

thomergil commented 2 weeks ago

The problem is that your example does not show where piCamera.js comes from when building locally.

TzuHuanTai commented 2 weeks ago

I'm not sure your development flow. If I build locally, I would use npm link picamera.js, which will be list in the local npm, and no matter Angular/Vue/React can read the package and use it instantly. Let the framework's bundle tool handle the rest of chores. I think it'd make things easier.

thomergil commented 2 weeks ago

Where is your demo index.html and how do I find it from README.md? Would be good to include a link. :)

TzuHuanTai commented 2 weeks ago

https://github.com/TzuHuanTai/PiCamera.js?tab=readme-ov-file#demo

It's deployed on the github pages already.

thomergil commented 2 weeks ago

But that's not a full example, it does not include the <video> element.

thomergil commented 2 weeks ago

You should add a link to https://github.com/TzuHuanTai/PiCamera.js/blob/main/demo/index.html in README.md

TzuHuanTai commented 2 weeks ago

Thanks your advice! I updated the readme.md.

thomergil commented 2 weeks ago

Thanks.