Recherche avancée

Médias (91)

Autres articles (53)

  • Amélioration de la version de base

    13 septembre 2013

    Jolie sélection multiple
    Le plugin Chosen permet d’améliorer l’ergonomie des champs de sélection multiple. Voir les deux images suivantes pour comparer.
    Il suffit pour cela d’activer le plugin Chosen (Configuration générale du site > Gestion des plugins), puis de configurer le plugin (Les squelettes > Chosen) en activant l’utilisation de Chosen dans le site public et en spécifiant les éléments de formulaires à améliorer, par exemple select[multiple] pour les listes à sélection multiple (...)

  • Menus personnalisés

    14 novembre 2010, par

    MediaSPIP utilise le plugin Menus pour gérer plusieurs menus configurables pour la navigation.
    Cela permet de laisser aux administrateurs de canaux la possibilité de configurer finement ces menus.
    Menus créés à l’initialisation du site
    Par défaut trois menus sont créés automatiquement à l’initialisation du site : Le menu principal ; Identifiant : barrenav ; Ce menu s’insère en général en haut de la page après le bloc d’entête, son identifiant le rend compatible avec les squelettes basés sur Zpip ; (...)

  • Publier sur MédiaSpip

    13 juin 2013

    Puis-je poster des contenus à partir d’une tablette Ipad ?
    Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir

Sur d’autres sites (6225)

  • Meta Receives a Record GDPR Fine from The Irish Data Protection Commission

    29 mai 2023, par Erin — GDPR

    The Irish Data Protection Commission (the DPC) issued a €1.2 billion fine to Meta on May, 22nd 2023 for violating the General Data Protection Regulation (GDPR). 

    The regulator ruled that Meta was unlawfully transferring European users’ data to its US-based servers and taking no sufficient measures for ensuring users’ privacy. 

    Meta must now suspend data transfer within five months and delete EU/EEA users’ personal data that was illegally transferred across the border. Or they risk facing another round of repercussions. 

    Meta continued to transfer personal user data to the USA following an earlier ruling of The Court of Justice of the European Union (CJEU), which already address problematic EU-U.S. data flows. Meta continued those transfers on the basis of the updated Standard Contractual Clauses (“SCCs”), adopted by the European Commission in 2021. 

    The Irish regulator successfully proved that these arrangements had not sufficiently addressed the “fundamental rights and freedoms” of the European data subjects, outlined in the CJEU ruling. Meta was not doing enough to protect EU users’ data against possible surveillance and unconsented usage by US authorities or other authorised entities.

    Why European Regulators Are After The US Big Tech Firms ? 

    GDPR regulations have been a sore area of compliance for US-based big tech companies. 

    Effectively, they had to adopt a host of new measures for collecting user consent, ensuring compliant data storage and the right to request data removal for a substantial part of their user bases. 

    The wrinkle, however, is that companies like Google and Meta among others, don’t have separate data processing infrastructure for different markets. Instead, all the user data gets commingled on the companies’ servers, which are located in the US. 

    Data storage facilities’ location is an issue. In 2020, the CJEU made a historical ruling, called the invalidation of the Privacy Shield. Originally, international companies were allowed to transfer data between the EU and the US if they adhered to seven data protection principles. This arrangement was called the Privacy Shield. 

    However, the continuous investigation found that the Privacy Shield scheme was not GDPR compliant and therefore companies could no longer use it to justify cross-border data transfers.

    The invalidation of the Privacy Shield gave ground for further investigations of the big tech companies’ compliance statuses. 

    In March 2022, the Irish DPC issued the first €17 million fine to Meta for “insufficient technical and organisational measures to ensure information security of European users”. In September 2022, Meta was again hit with a €405 million fine for Instagram breaching GDPR principles. 

    2023 began with another series of rulings, with the DPC concluding that Meta had breaches of the GDPR relating to its Facebook service (€210 million fine) and breaches related to Instagram (€180 million fine). 

    Clearly, Meta already knew they weren’t doing enough for GDPR compliance and yet they refused to take privacy-focused action

    Is Google GDPR Compliant ?

    Google has a similar “track record” as Meta when it comes to ensuring full compliance with the GDPR. Although Google has said to provide users with more controls for managing their data privacy, the proposed solutions are just scratching the surface. 

    In the background, Google continues to leverage its ample reserves of user browsing, behavioural and device data in product development and advertising. 

    In 2022, the Irish Council for Civil Liberties (ICCL) found that Google used web users’ information in its real-time bidding ad system without their knowledge or consent. The French data regulator (CNIL), in turn, fined Google for €150 million because of poor cookie consent banners the same year. 

    Google Analytics GDPR compliance status is, however, the bigger concern.

    Neither Google Univeral Analytics (UA) nor Google Analytics 4 are GDPR compliant, following the Privacy Shield framework invalidation in 2020. 

    Fines from individual regulators in Sweden, France, Austria, Italy, Denmark, Finland and Norway ruled that Google Analytics is non-GDPR compliant and is therefore illegal to use. 

    The regulatory rulings not just affect Google, but also GA users. Because the product is in breach of European privacy laws, people using it are complacent. Privacy groups like noyb, for example, are exercising their right to sue individual websites, using Google Analytics.

    How to Stay GDPR Compliant With Website Analytics 

    To avoid any potential risk exposure, selectively investigate each website analytics provider’s data storage and management practices. 

    Inquire about the company’s data storage locations among the first things. For example, Matomo Cloud keeps all the data in the EU, while Matomo On-Premise edition gives you the option to store data in any country of your choice. 

    Secondly, ask about their process for consent tracking and subsequent data analysis. Our website analytics product is fully GDPR compliant as we have first-party cookies enabled by default, offer a convenient option of tracking out-outs, provide a data removal mechanism and practice safe data storage. In fact, Matomo was approved by the French Data Protection Authority (CNIL) as one of the few web analytics apps that can be used to collect data without tracking consent

    Using an in-built GDPR Manager, Matomo users can implement the right set of controls for their market and their industry. For example, you can implement extra data or IP anonymization ; disable visitor logs and profiles. 

    Thanks to our privacy-by-design architecture and native controls, users can make their Matomo analytics compliant even with the strictest privacy laws like HIPAA, CCPA, LGPD and PECR. 

    Learn more about GDPR-friendly website analytics.

    Final Thoughts

    Since the GDPR came into effect in 2018, over 1,400 fines have been given to various companies in breach of the regulations. Meta and Google have been initially lax in response to European regulatory demands. But as new fines follow and the consumer pressure mounts, Big Tech companies are forced to take more proactive measures : add opt-outs for personalised ads and introduce an alternative mechanism to third-party cookies

    Companies, using non-GDPR-compliant tools risk finding themselves in the crossfire of consumer angst and regulatory criticism. To operate an ethical, compliant business consider privacy-focused alternatives to Google products, especially in the area of website analytics. 

  • Code can not read property 1 of undefined [closed]

    25 mai 2023, par Jesse Copas

    I'm a very new programmer and am working on a Tdarr plugin in JS.
Everything works fine until a 4k file tries to get transcoded and it fails with this log

    


    2023-05-24T19:09:54.906Z ZoBKWMMKG:Node\[hidden-hog\]:Worker\[tall-tuna\]:{"pluginInputs":{"BitRate":"4000","ResolutionSelection":"1080p","Container":"mkv","AudioType":"AAC","FrameRate":"24"}}

2023-05-24T19:09:54.907Z ZoBKWMMKG:Node\[hidden-hog\]:Worker\[tall-tuna\]:Error TypeError: Cannot read property '1' of undefined


    


    It's saying that it's unable to read property 1 of undefined and I'm looked and looked and looked and can't find what it is referring to. Hoping to get another set of eyes on it
The plugin Code is here

    


    /* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
/* eslint-disable no-restricted-globals */
const details = () => ({
  id: 'Tdarr_Plugin_Jeso_AV1_HandBrake_Transcode',
  Stage: 'Pre-processing',
  Name: 'AV1 HandBrake Transcoder',
  Type: 'Video',
  Operation: 'Transcode',
  Description: 'Transcodes to AV1 at the selected Bitrate. This is best used with Remux Files.',
  Version: '2.1.3',
  Tags: 'HandBrake,configurable',
  Inputs: [
    {
      name: 'BitRate',
      type: 'string',
      defaultValue: '4000',
      inputUI: {
        type: 'text',
      },
      tooltip: `
        ~ Requested Bitrate ~ \\n
        Put in the Bitrate you want to process to in Kbps. For example 4000Kbps is 4Mbps. `,
    },
    {
      name: 'ResolutionSelection',
      type: 'string',
      defaultValue: '1080p',
      inputUI: {
        type: 'dropdown',
        options: [
          '8KUHD',
          '4KUHD',
          '1080p',
          '720p',
          '480p',
        ],
      },
      // eslint-disable-next-line max-len
      tooltip: 'Any Resolution larger than this will become this Resolution same as the bitrate if the Res is lower than the selected it will use the res of the file as to not cause bloating of file size.',
    },
    {
      name: 'Container',
      type: 'string',
      defaultValue: 'mkv',
      inputUI: {
        type: 'dropdown',
        options: [
          'mp4',
          'mkv',
        ],
      },
      tooltip: ` Container Type \\n\\n
          mkv or mp4.\\n`,
    },
    {
      name: 'AudioType',
      type: 'string',
      defaultValue: 'AAC',
      inputUI: {
        type: 'dropdown',
        options: [
          'AAC',
          'EAC3',
          'MP3',
          'Vorbis',
          'Flac16',
          'Flac24',
        ],
      },
      // eslint-disable-next-line max-len
      tooltip: 'Set Audio container type that you want to use',
    },
    {
      name: 'FrameRate',
      type: 'string',
      defaultValue: '24',
      inputUI: {
        type: 'text',
      },
      // eslint-disable-next-line max-len
      tooltip: 'If the files framerate is higher than 24 and you want to maintain that framerate you can do so here',
    },
  ],
});
const MediaInfo = {
  videoHeight: '',
  videoWidth: '',
  videoFPS: '',
  videoBR: '',
  videoBitDepth: '',
  overallBR: '',
  videoResolution: '',
}; // var MediaInfo
// Easier for our functions if response has global scope.
const response = {
  processFile: false,
  preset: '',
  container: '.mkv',
  handBrakeMode: true,
  FFmpegMode: false,
  reQueueAfter: true,
  infoLog: '',
}; // var response
// Finds the first video stream and populates some useful variables
function getMediaInfo(file) {
  let videoIdx = -1;
  for (let i = 0; i < file.ffProbeData.streams.length; i += 1) {
    const strstreamType = file.ffProbeData.streams[i].codec_type.toLowerCase();
    // Looking For Video
    // Check if stream is a video.
    if (videoIdx === -1 && strstreamType === 'video') {
      videoIdx = i;
      // get video streams resolution
      MediaInfo.videoResolution = `${file.ffProbeData.streams[i].height}x${file.ffProbeData.streams[i].width}`;
      MediaInfo.videoHeight = Number(file.ffProbeData.streams[i].height);
      MediaInfo.videoWidth = Number(file.ffProbeData.streams[i].width);
      MediaInfo.videoFPS = Number(file.mediaInfo.track[i + 1].FrameRate) || 25;
      // calulate bitrate from dimensions and fps of file
      MediaInfo.videoBR = (MediaInfo.videoHeight * MediaInfo.videoWidth * MediaInfo.videoFPS * 0.08).toFixed(0);
    }
  }
} // end  getMediaInfo()
// define resolution order from ResolutionSelection from biggest to smallest
const resolutionOrder = ['8KUHD', '4KUHD', '1080p', '720p', '480p'];
// define the width and height of each resolution from the resolution order
const resolutionsdimensions = {
  '8KUHD': '--width 7680 --height 4320',
  '4KUHD': '--width 3840 --height 2160',
  '1080p': '--width 1920 --height 1080',
  '720p': '--width 1280 --height 720',
  '480p': '--width 640 --height 480',
};
// eslint-disable-next-line no-unused-vars
const plugin = (file, librarySettings, inputs) => {
  // eslint-disable-next-line no-unused-vars
  const importFresh = require('import-fresh');
  // eslint-disable-next-line no-unused-vars
  const library = importFresh('../methods/library.js');
  // eslint-disable-next-line no-unused-vars
  const lib = require('../methods/lib')();
  // Get the selected resolution from the 'ResolutionSelection' variable
  const selectedResolution = inputs.ResolutionSelection;
  getMediaInfo(file);
  // use mediainfo to match height and width to a resolution on resolutiondimensions
  let dimensions = resolutionsdimensions[selectedResolution];
  // if the file is smaller than the selected resolution then use the file resolution
  if (MediaInfo.videoHeight < dimensions.split(' ')[3] || MediaInfo.videoWidth < dimensions.split(' ')[1]) {
    dimensions = `--width ${MediaInfo.videoWidth} --height ${MediaInfo.videoHeight}`;
    // eslint-disable-next-line brace-style
  }
  // read the bitrate of the video stream
  let videoBitRate = MediaInfo.videoBR;
  // if videoBitrate is over 1000000 devide by 100 to get the bitrate in Kbps
  if (videoBitRate > 1000000) {
    videoBitRate /= 100;
  } else { videoBitRate /= 1000; }
  // if VideoBitrate is smaller than selected bitrate then use the videoBitrate
  if (videoBitRate < inputs.BitRate) {
    // eslint-disable-next-line no-param-reassign
    inputs.BitRate = videoBitRate;
    // eslint-disable-next-line brace-style
  }
  // if VideoBitrate is larger than selected bitrate then use the selected bitrate
  else {
    // eslint-disable-next-line no-self-assign, no-param-reassign
    inputs.BitRate = inputs.BitRate;
  }

  //Skip Transcoding if File is already AV1
  if (file.ffProbeData.streams[0].codec_name === 'av1') {
    response.processFile = false;
    response.infoLog += 'File is already AV1 \n';
    return response;
  }
  // eslint-disable-next-line no-constant-condition
  if ((true) || file.forceProcessing === true) {
    // eslint-disable-next-line max-len
    response.preset = `--encoder svt_av1 -b ${inputs.BitRate} -r ${inputs.FrameRate} -E ${inputs.AudioType} -f ${inputs.Container} --no-optimize ${dimensions} --crop 0:0:0:0`;
    response.container = `.${inputs.Container}`;
    response.handbrakeMode = true;
    response.ffmpegMode = false;
    response.processFile = true;
    response.infoLog += `File is being transcoded at ${inputs.BitRate} Kbps to ${dimensions} as ${inputs.Container} \n`;
    return response;
  }
  response.infoLog += 'File is being transcoded using custom arguments \n';
  return response;
};
  };

module.exports.details = details;
module.exports.plugin = plugin;


    


    Tried transcoding 4k files down to 1080p but it fails due to that undefined error. All Res 1080p and lower that I have tried work correctly

    


    EDIT : I used Console.log and got this back

    


    [2023-05-24T23:29:51.001] [ERROR] Tdarr_Server - Error running MediaInfo 1&#xA;[2023-05-24T23:29:51.004] [ERROR] Tdarr_Server - RangeError: Maximum call stack size exceeded&#xA;    at x (<anonymous>:wasm-function[381]:0x15c4d)&#xA;    at <anonymous>:wasm-function[46]:0x5dc0&#xA;    at <anonymous>:wasm-function[652]:0x21cb9&#xA;    at <anonymous>:wasm-function[1023]:0x47018&#xA;    at <anonymous>:wasm-function[853]:0x37827&#xA;    at <anonymous>:wasm-function[3684]:0xf4884&#xA;    at <anonymous>:wasm-function[3516]:0xeb5b7&#xA;    at <anonymous>:wasm-function[1061]:0x487c9&#xA;    at <anonymous>:wasm-function[795]:0x3006d&#xA;    at <anonymous>:wasm-function[3628]:0xf01cc&#xA;[2023-05-24T23:29:51.006] [ERROR] Tdarr_Server - Error running MediaInfo 2&#xA;[2023-05-24T23:29:51.006] [ERROR] Tdarr_Server - RangeError: Maximum call stack size exceeded&#xA;    at x (<anonymous>:wasm-function[381]:0x15c4d)&#xA;    at <anonymous>:wasm-function[46]:0x5dc0&#xA;    at <anonymous>:wasm-function[652]:0x21cb9&#xA;    at <anonymous>:wasm-function[1023]:0x47018&#xA;    at <anonymous>:wasm-function[853]:0x37827&#xA;    at <anonymous>:wasm-function[3684]:0xf4884&#xA;    at <anonymous>:wasm-function[3516]:0xeb5b7&#xA;    at <anonymous>:wasm-function[1061]:0x487c9&#xA;    at <anonymous>:wasm-function[795]:0x3006d&#xA;    at <anonymous>:wasm-function[3628]:0xf01cc&#xA;[2023-05-24T23:29:58.220] [ERROR] Tdarr_Server - Error running MediaInfo 1&#xA;[2023-05-24T23:29:58.223] [ERROR] Tdarr_Server - RangeError: Maximum call stack size exceeded&#xA;    at x (<anonymous>:wasm-function[381]:0x15c4d)&#xA;    at <anonymous>:wasm-function[46]:0x5dc0&#xA;    at <anonymous>:wasm-function[652]:0x21cb9&#xA;    at <anonymous>:wasm-function[1023]:0x47018&#xA;    at <anonymous>:wasm-function[853]:0x37827&#xA;    at <anonymous>:wasm-function[3684]:0xf4884&#xA;    at <anonymous>:wasm-function[3516]:0xeb5b7&#xA;    at <anonymous>:wasm-function[1061]:0x487c9&#xA;    at <anonymous>:wasm-function[795]:0x3006d&#xA;    at <anonymous>:wasm-function[3628]:0xf01cc&#xA;[2023-05-24T23:29:58.224] [ERROR] Tdarr_Server - Error running MediaInfo 2&#xA;[2023-05-24T23:29:58.224] [ERROR] Tdarr_Server - RangeError: Maximum call stack size exceeded&#xA;    at x (<anonymous>:wasm-function[381]:0x15c4d)&#xA;    at <anonymous>:wasm-function[46]:0x5dc0&#xA;    at <anonymous>:wasm-function[652]:0x21cb9&#xA;    at <anonymous>:wasm-function[1023]:0x47018&#xA;    at <anonymous>:wasm-function[853]:0x37827&#xA;    at <anonymous>:wasm-function[3684]:0xf4884&#xA;    at <anonymous>:wasm-function[3516]:0xeb5b7&#xA;    at <anonymous>:wasm-function[1061]:0x487c9&#xA;    at <anonymous>:wasm-function[795]:0x3006d&#xA;    at <anonymous>:wasm-function[3628]:0xf01cc&#xA;</anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous></anonymous>

    &#xA;

  • Flask app using OpenCv crash when i start recording

    17 mai 2023, par Mulham Darwish

    I build this flask app to live stream security cameras and the live stream works with the screenshot function but when start recording it crash but few times same code it worked and saved the video here the code. with the html file using js.

    &#xA;

    from flask import Flask, render_template, Response, request&#xA;import cv2&#xA;import os&#xA;import time&#xA;import threading&#xA;import requests&#xA;&#xA;app = Flask(__name__)&#xA;&#xA;# Define the IP cameras&#xA;cameras = [&#xA;    {&#x27;url&#x27;: &#x27;rtsp://****:*****@******&#x27;, &#x27;name&#x27;: &#x27;Camera 1&#x27;},&#xA;    {&#x27;url&#x27;: &#x27;rtsp://****:*****@******&#x27;, &#x27;name&#x27;: &#x27;Camera 2&#x27;},&#xA;    {&#x27;url&#x27;: &#x27;rtsp://****:*****@******&#x27;, &#x27;name&#x27;: &#x27;Camera 3&#x27;},&#xA;    {&#x27;url&#x27;: &#x27;rtsp://****:*****@******&#x27;, &#x27;name&#x27;: &#x27;Camera 4&#x27;}&#xA;]&#xA;&#xA;# Create a VideoCapture object for each camera&#xA;capture_objs = [cv2.VideoCapture(cam[&#x27;url&#x27;]) for cam in cameras]&#xA;stop_events = {i: threading.Event() for i in range(len(cameras))}&#xA;# Define the directory to save the recorded videos&#xA;recording_dir = os.path.join(os.getcwd(), &#x27;recordings&#x27;)&#xA;&#xA;# Ensure the recording directory exists&#xA;if not os.path.exists(recording_dir):&#xA;    os.makedirs(recording_dir)&#xA;&#xA;# Define the function to capture and save a video&#xA;def record_video(camera_index, stop_recording):&#xA;    # Define the codec and file extension&#xA;    fourcc = cv2.VideoWriter_fourcc(*&#x27;mp4v&#x27;)&#xA;    file_extension = &#x27;.mp4&#x27;&#xA;&#xA;    # Get the current timestamp for the filename&#xA;    timestamp = time.strftime("%Y%m%d-%H%M%S")&#xA;&#xA;    # Define the filename and path&#xA;    filename = f&#x27;{cameras[camera_index]["name"]}_{timestamp}{file_extension}&#x27;&#xA;    filepath = os.path.join(recording_dir, filename)&#xA;&#xA;    # Create a VideoWriter object to save the video&#xA;    width = int(capture_objs[camera_index].get(cv2.CAP_PROP_FRAME_WIDTH))&#xA;    height = int(capture_objs[camera_index].get(cv2.CAP_PROP_FRAME_HEIGHT))&#xA;    fps = int(capture_objs[camera_index].get(cv2.CAP_PROP_FPS))&#xA;    video_writer = cv2.VideoWriter(filepath, fourcc, fps, (width, height))&#xA;&#xA;    # Capture frames and write them to the file&#xA;    while True:&#xA;        if stop_recording.is_set():&#xA;            break  # stop recording if stop_recording is set&#xA;        ret, frame = capture_objs[camera_index].read()&#xA;        if ret:&#xA;            video_writer.write(frame)&#xA;        else:&#xA;            break&#xA;&#xA;    # Release the VideoWriter object and the VideoCapture object&#xA;    video_writer.release()&#xA;    capture_objs[camera_index].release()&#xA;&#xA;@app.route(&#x27;/&#x27;)&#xA;def index():&#xA;    # Render the index page with the list of cameras&#xA;    return render_template(&#x27;index.html&#x27;, cameras=cameras)&#xA;&#xA;def generate(camera_index):&#xA;    # Generate frames from the video feed&#xA;    while True:&#xA;        ret, frame = capture_objs[camera_index].read()&#xA;        if not ret:&#xA;            break&#xA;&#xA;        # Encode the frame as JPEG&#xA;        _, jpeg = cv2.imencode(&#x27;.jpg&#x27;, frame)&#xA;&#xA;        # Yield the frame as a Flask response&#xA;        yield (b&#x27;--frame\r\n&#x27;&#xA;               b&#x27;Content-Type: image/jpeg\r\n\r\n&#x27; &#x2B; jpeg.tobytes() &#x2B; b&#x27;\r\n&#x27;)&#xA;&#xA;@app.route(&#x27;/video_feed&#x27;)&#xA;def video_feed():&#xA;    # Get the camera index from the request arguments&#xA;    camera_index = int(request.args.get(&#x27;camera_index&#x27;))&#xA;&#xA;    # Generate the video feed&#xA;    return Response(generate(camera_index),&#xA;                    mimetype=&#x27;multipart/x-mixed-replace; boundary=frame&#x27;)&#xA;&#xA;@app.route(&#x27;/record&#x27;, methods=[&#x27;POST&#x27;])&#xA;def record():&#xA;    # Get the camera index from the request form&#xA;    camera_index = int(request.form[&#x27;camera_index&#x27;])&#xA;&#xA;    stop_recording = stop_events[camera_index]  # get the stop_recording event for the camera&#xA;    thread = threading.Thread(target=record_video, args=(camera_index, stop_recording))&#xA;    thread.start()  # start a thread to record video&#xA;&#xA;    # Return a response indicating that the recording has started&#xA;    return &#x27;Recording started.&#x27;&#xA;&#xA;@app.route(&#x27;/stop_record&#x27;, methods=[&#x27;POST&#x27;])&#xA;def stop_record():&#xA;    # Get the camera index from the request form&#xA;    camera_index = int(request.form[&#x27;camera_index&#x27;])&#xA;&#xA;    # Set the stop_recording event for the corresponding camera thread&#xA;    stop_events[camera_index].set()&#xA;&#xA;    # Return a response indicating that recording has been stopped&#xA;    return &#x27;Recording stopped.&#x27;&#xA;&#xA;@app.route(&#x27;/screenshot&#x27;, methods=[&#x27;POST&#x27;])&#xA;def take_screenshot():&#xA;    # Take a screenshot of the video stream and save it as a file&#xA;    camera = capture_objs[int(request.form[&#x27;camera_id&#x27;])]&#xA;    success, frame = camera.read()&#xA;    if success:&#xA;        timestamp = time.strftime("%Y%m%d-%H%M%S")&#xA;        filename = f&#x27;screenshot_{timestamp}.jpg&#x27;&#xA;        cv2.imwrite(filename, frame)&#xA;        return &#x27;Screenshot taken and saved&#x27;&#xA;    else:&#xA;        return &#x27;Failed to take screenshot&#x27;&#xA;&#xA;if __name__ == &#x27;__main__&#x27;:&#xA;    app.run()&#xA;

    &#xA;

    I tried to update ffmpeg to the latest version and installed pip install opencv-python-headless and installed pip install opencv-python but most of the time i come to this crash code

    &#xA;

    * Serving Flask app &#x27;run&#x27;&#xA;* Debug mode: off&#xA;WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.&#xA; * Running on http://127.0.0.1:5000&#xA;Press CTRL&#x2B;C to quit&#xA;127.0.0.1 - - [17/May/2023 13:24:11] "GET / HTTP/1.1" 200 -&#xA;127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=0 HTTP/1.1" 200 -&#xA;127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=1 HTTP/1.1" 200 -&#xA;127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=2 HTTP/1.1" 200 -&#xA;127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=3 HTTP/1.1" 200 -&#xA;127.0.0.1 - - [17/May/2023 13:24:44] "GET / HTTP/1.1" 200 -&#xA;127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=3 HTTP/1.1" 200 -&#xA;127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=0 HTTP/1.1" 200 -&#xA;127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=1 HTTP/1.1" 200 -&#xA;127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=2 HTTP/1.1" 200 -&#xA;[h264 @ 0x5605285fc5c0] error while decoding MB 28 29, bytestream -9&#xA;[h264 @ 0x560529110040] error while decoding MB 15 37, bytestream -6&#xA;[h264 @ 0x560528624980] error while decoding MB 45 45, bytestream -23&#xA;[h264 @ 0x5605286f1900] error while decoding MB 50 34, bytestream -7&#xA;[h264 @ 0x5605285fc5c0] error while decoding MB 25 9, bytestream -17&#xA;[h264 @ 0x5605292b0080] error while decoding MB 28 41, bytestream -5&#xA;[h264 @ 0x560528660040] error while decoding MB 101 45, bytestream -17&#xA;[h264 @ 0x5605285fc5c0] error while decoding MB 42 44, bytestream -5&#xA;[h264 @ 0x5605286f1900] error while decoding MB 118 42, bytestream -9&#xA;[h264 @ 0x560529110040] error while decoding MB 92 43, bytestream -5&#xA;[h264 @ 0x560528660040] error while decoding MB 99 34, bytestream -11&#xA;[h264 @ 0x56052932b0c0] error while decoding MB 92 36, bytestream -13&#xA;[h264 @ 0x560528667ac0] error while decoding MB 44 54, bytestream -5&#xA;[h264 @ 0x560529110040] error while decoding MB 93 33, bytestream -7&#xA;[h264 @ 0x5605286dd880] error while decoding MB 27 37, bytestream -19&#xA;[h264 @ 0x560528660040] error while decoding MB 66 56, bytestream -9&#xA;127.0.0.1 - - [17/May/2023 13:36:45] "POST /record HTTP/1.1" 200 -&#xA;Assertion fctx->async_lock failed at libavcodec/pthread_frame.c:175&#xA;Aborted (core dumped)&#xA;

    &#xA;