(FRONT) FRONT (2022)

Electron learning

1. Difference between Electron desktop application and HTML page

First main point - clearly understand what is Electron application, what is not electron application. This is HTML page that working in embedded to WebStorm HttpServer.



This is WebPage that working in separate installed Web Server.



And finally, clear Electron application - desktop application that started as "electron ." and execution start from call script Index.js



Sometimes this looking tricky because HTML page and Electron application working simultaneously and doing the doing the same job.



And in this point need to clear understand how HTML page working in Browser and how Working Electron application - executing script Index.js



And pay attention that Electron application is Node.JS application and require Node.JS engine!



2. Electron application would to distribute as native desktop application in various Environment - Linux, Windows, Mac. There are procedure that create native executed file.



In this case Electron application working fine, but result of compilation to native desktop application faced with Content-Security-Policy restriction. This is most difficult trouble for me, and I never can clearly resolve this trouble - Electron video player with cashing and CSP policy, but this is another question. Many application can working without access to local resource, in this case Browser engine restriction not applicable.


3. Reading application parameters and reading from command line.

Most interesting case is application parameter, this opportunity allow start different HTML page or different branch of Electron script.


4. Difference between main process and rendering process.

This is another most critical point - where is main Electron thread and where is Browser rendering thread? In code below line 10-18 is main thread but callback from line 41 is rendering thread.


   1:  // Index.htm running in rendering process
   2:  
   3:  const http = require('http');
   4:  const { app, BrowserWindow } = require('electron');
   5:  const path = require('path');
   6:  const fs = require('fs');
   7:  const { exec } = require('child_process');
   8:  
   9:  //correct path to the video file for distribute application
  10:  const videoPath = path.join(app.getAppPath(), 'tst1.mp4');
  11:  
  12:  // Read the config.json file
  13:  const configPath = path.join(__dirname, 'config.json');
  14:  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
  15:  
  16:  const version = process.argv[2] || '0'; // default from command line
  17:  const port = config.port || 7070; // Default to port 7070
  18:  console.log(`version=${version}`);
  19:  
  20:  function createWindow() {
  21:      const mainWindow = new BrowserWindow({
  22:          width: 800,
  23:          height: 600,
  24:          webPreferences: {
  25:              nodeIntegration: true, // Enable Node.js integration
  26:              contextIsolation: false, // Disable context isolation
  27:              allowRunningInsecureContent: true, // Allow insecure content (e.g., local files)
  28:          },
  29:      });
  30:  
  31:      // Load the index.html file
  32:      mainWindow.loadFile('index1.html');
  33:  
  34:      // Pass the video path to the renderer process
  35:      mainWindow.webContents.on('did-finish-load', () => {
  36:          console.log(`videoPath=${videoPath}`);
  37:          mainWindow.webContents.send('video-path', videoPath);
  38:      });
  39:  }
  40:  
  41:  app.whenReady().then(() => {
  42:  
  43:      //this code runs in the main process
  44:      if (version === '2') {
  45:          console.log('Starting HTTP server for version 2...');
  46:          const serverProcess = exec('node http-server.js');
  47:  
  48:          serverProcess.stdout.on('data', (data) => {
  49:              console.log('HTTP server:', data.toString());
  50:          });
  51:  
  52:          serverProcess.stderr.on('data', (data) => {
  53:              console.error('HTTP server error:', data.toString());
  54:          });
  55:  
  56:          serverProcess.on('close', (code) => {
  57:              console.log('HTTP server process exited with code ' + code);
  58:          });
  59:      }
  60:      else if (version === '3') {
  61:          console.log('Starting HTTP server for version 3...');
  62:          const serverProcess = exec('node video-server.js');
  63:      }
  64:  
  65:      createWindow();
  66:      app.on('activate', () => {
  67:          if (BrowserWindow.getAllWindows().length === 0) {
  68:              createWindow();
  69:          }
  70:      });
  71:  });
  72:  
  73:  app.on('window-all-closed', () => {
  74:      if (process.platform !== 'darwin') {
  75:          app.quit();
  76:      }
  77:  });
  78:  

6. We can create separate child Node.JS process from rendering thread.

Other critical point of Electron development. We can create separate Node process as child of rendering process and in this thread we can open Http server or media server.

So, Webserver can working as external to Electron application process and we can watch HTML page in this Http server



BUT, we can start child Node.JS process from rendering process:


   1:  const http = require('http');
   2:  const port = 7070;
   3:  
   4:  const server = http.createServer((req, res) => {
   5:      console.log('Incoming request:', req.url);
   6:      res.end('Hello from HTTP server!');
   7:  });
   8:  
   9:  server.listen(port, () => {
  10:      console.log('HTTP server listening on port ' + port);
  11:  });
  12:  

In this case Http server just send message to Browser and close request.



Also I have started separate Node.JS Video server process that read local video file and send it to port 5050, where Browser expect vide stream.


   1:  const http = require('http');
   2:  const fs = require('fs');
   3:  const path = require('path');
   4:  
   5:  // Create an HTTP server
   6:  const server = http.createServer((req, res) => {
   7:      // Path to the video file
   8:      const videoPath = path.join(__dirname, 'tst1.mp4');
   9:  
  10:      // Check if the file exists
  11:      fs.access(videoPath, fs.constants.F_OK, (err) => {
  12:          if (err) {
  13:              // If the file doesn't exist, send a 404 response
  14:              res.writeHead(404, { 'Content-Type': 'text/plain' });
  15:              res.end('Video not found');
  16:              return;
  17:          }
  18:  
  19:          // Get the file size for the Content-Length header
  20:          const stat = fs.statSync(videoPath);
  21:          const fileSize = stat.size;
  22:  
  23:          // Set the appropriate headers for video streaming
  24:          res.writeHead(200, {
  25:              'Content-Type': 'video/mp4',
  26:              'Content-Length': fileSize,
  27:          });
  28:  
  29:          // Create a read stream from the video file and pipe it to the response
  30:          const videoStream = fs.createReadStream(videoPath);
  31:          videoStream.pipe(res);
  32:      });
  33:  });
  34:  
  35:  // Start the server on port 5050
  36:  server.listen(5050, () => {
  37:      console.log('Server listening on port 8080');
  38:  });
  39:  

If we need communicate with Video Server, we can not write:


   1:  <!DOCTYPE html>
   2:  <html lang="en">
   3:  <head>
   4:    <meta charset="UTF-8">
   5:    <meta http-equiv="Content-Security-Policy" content="default-src 'self' file:; script-src 'self' 'unsafe-inline'; media-src 'self' file:;">
   6:    <title>Electron Video Player</title>
   7:  </head>
   8:  <body>
   9:  <h1>Local Video Player</h1>
  10:  <video controls width="640" height="360">
  11:    <!--<source src="file:///E:/Angular/JS-TEST1/Electron/tst1.mp4" type="video/mp4">-->
  12:    <source src="./tst1.mp4" type="video/mp4">
  13:    Your browser does not support the video tag.
  14:  </video>
  15:  </body>
  16:  </html>

In this case we need more sophisticated Index.html page:


   1:  <!DOCTYPE html>
   2:  <html lang="en">
   3:  <head>
   4:    <meta charset="UTF-8">
   5:    <meta http-equiv="Content-Security-Policy" content="default-src 'self' file:; script-src 'self' 'unsafe-inline'; media-src 'self' file:;">
   6:    <title>Electron Video Player</title>
   7:  </head>
   8:  <body>
   9:  <h1>Local Video Player</h1>
  10:  <video id="videoPlayer" controls width="640" height="360">
  11:    Your browser does not support the video tag.
  12:  </video>
  13:   
  14:  <script>
  15:    const { ipcRenderer } = require('electron');
  16:   
  17:    // Receive the video path from the main process
  18:    ipcRenderer.on('video-path', (event, videoPath) => {
  19:      const videoPlayer = document.getElementById('videoPlayer');
  20:      const source = document.createElement('source');
  21:   
  22:      source.src = videoPath;
  23:      source.type = 'video/mp4';
  24:   
  25:      videoPlayer.appendChild(source);
  26:      videoPlayer.load();
  27:    });
  28:  </script>
  29:  </body>
  30:  </html>

7. Other Electron approach - ElectronNET host with C# code


8. Also I take 4 lectures about Electron:




Electron context:




AngularElectron context:



Comments ( )
Link to this page: http://www.vb-net.com/ElectronLearning/Index.htm
< THANKS ME>