Recherche avancée

Médias (0)

Mot : - Tags -/interaction

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (53)

  • Gestion des droits de création et d’édition des objets

    8 février 2011, par

    Par défaut, beaucoup de fonctionnalités sont limitées aux administrateurs mais restent configurables indépendamment pour modifier leur statut minimal d’utilisation notamment : la rédaction de contenus sur le site modifiables dans la gestion des templates de formulaires ; l’ajout de notes aux articles ; l’ajout de légendes et d’annotations sur les images ;

  • Les images

    15 mai 2013
  • Supporting all media types

    13 avril 2011, par

    Unlike most software and media-sharing platforms, MediaSPIP aims to manage as many different media types as possible. The following are just a few examples from an ever-expanding list of supported formats : images : png, gif, jpg, bmp and more audio : MP3, Ogg, Wav and more video : AVI, MP4, OGV, mpg, mov, wmv and more text, code and other data : OpenOffice, Microsoft Office (Word, PowerPoint, Excel), web (html, CSS), LaTeX, Google Earth and (...)

Sur d’autres sites (4868)

  • How to Record Video of a Dynamic Div Containing Multiple Media Elements in React Konva ?

    14 septembre 2024, par Humayoun Saeed

    I'm working on a React application where I need to record a video of a specific div with the class name "layout." This div contains multiple media elements (such as images and videos) that are dynamically rendered inside divisions. I've tried several approaches, including using MediaRecorder, canvas-based recording with html2canvas, RecordRTC, and even ffmpeg, but none seem to capture the entire div along with its dynamic content effectively.

    


    What would be the best approach to achieve this ? How can I record a video of this dynamically rendered div including all its media elements, ensuring a smooth capture of the transitions ?

    


    What I’ve Tried :
MediaRecorder API : Didn't work effectively for capturing the entire div and its elements.
html2canvas : Captures snapshots but struggles with smooth transitions between media elements.
RecordRTC HTML Element Recording : Attempts to capture the canvas, but the output video size is 0 bytes.
CanvasRecorder, FFmpeg, and various other libraries also didn't provide the desired result.

    


    import React, { useEffect, useState, useRef } from "react";&#xA;&#xA;const Preview = ({ layout, onClose }) => {&#xA;  const [currentContent, setCurrentContent] = useState([]);&#xA;  const totalDuration = useRef(0);&#xA;  const videoRefs = useRef([]); // Store refs to each video element&#xA;  const [totalTime, setTotalTime] = useState(0); // Add this line&#xA;  const [elapsedTime, setElapsedTime] = useState(0); // Track elapsed time in seconds&#xA;&#xA;  // video recording variable and state declaration&#xA;  //  video recorder end&#xA;  // for video record useffect&#xA;  // Function to capture the renderDivision content&#xA;&#xA;  const handleDownload = async () => {&#xA;    console.log("video downlaod function in developing mode.");&#xA;  };&#xA;&#xA;  // end video record useffect&#xA;&#xA;  // to apply motion and swtich in media of division start&#xA;  useEffect(() => {&#xA;    if (layout &amp;&amp; layout.divisions) {&#xA;      const content = layout.divisions.map((division) => {&#xA;        let divisionDuration = 0;&#xA;&#xA;        division.imageSrcs.forEach((src, index) => {&#xA;          const mediaDuration = division.durations[index]&#xA;            ? division.durations[index] * 1000 // Convert to milliseconds&#xA;            : 5000; // Fallback to 5 seconds if duration is missing&#xA;          divisionDuration &#x2B;= mediaDuration;&#xA;        });&#xA;&#xA;        return {&#xA;          division,&#xA;          contentIndex: 0,&#xA;          divisionDuration,&#xA;        };&#xA;      });&#xA;&#xA;      // Find the maximum duration&#xA;      const maxDuration = Math.max(...content.map((c) => c.divisionDuration));&#xA;&#xA;      // Filter divisions that have the max duration&#xA;      const maxDurationDivisions = content.filter(&#xA;        (c) => c.divisionDuration === maxDuration&#xA;      );&#xA;&#xA;      // Select the first one if there are multiple with the same max duration&#xA;      const selectedMaxDurationDivision = maxDurationDivisions[0];&#xA;&#xA;      totalDuration.current = selectedMaxDurationDivision.divisionDuration; // Update the total duration in milliseconds&#xA;&#xA;      setTotalTime(Math.floor(totalDuration.current / 1000000)); // Convert to seconds and set in state&#xA;&#xA;      // console.log(&#xA;      //   "Division with max duration (including ties):",&#xA;      //   selectedMaxDurationDivision&#xA;      // );&#xA;&#xA;      setCurrentContent(content);&#xA;    }&#xA;  }, [layout]);&#xA;&#xA;  useEffect(() => {&#xA;    if (currentContent.length > 0) {&#xA;      const timers = currentContent.map(({ division, contentIndex }, i) => {&#xA;        const duration = division.durations[contentIndex]&#xA;          ? division.durations[contentIndex] // Duration is already in ms&#xA;          : 5000; // Default to 5000ms if no duration is defined&#xA;&#xA;        const mediaElement = videoRefs.current[i];&#xA;        if (mediaElement &amp;&amp; mediaElement.pause) {&#xA;          mediaElement.pause();&#xA;        }&#xA;&#xA;        // Set up a timeout for each division to move to the next media after duration&#xA;        const timeoutId = setTimeout(() => {&#xA;          // Update content for each division independently&#xA;          updateContent(i, division, contentIndex, duration); // Move to the next content after duration&#xA;&#xA;          // Ensure proper cleanup&#xA;          if (contentIndex &#x2B; 1 >= division.imageSrcs.length) {&#xA;            clearTimeout(timeoutId); // Clear timeout to stop looping&#xA;          }&#xA;        }, duration);&#xA;&#xA;        // Cleanup timers on component unmount&#xA;        return timeoutId;&#xA;      });&#xA;&#xA;      // Return cleanup function to clear all timeouts&#xA;      return () => timers.forEach((timer) => clearTimeout(timer));&#xA;    }&#xA;  }, [currentContent]);&#xA;  // to apply motion and swtich in media of division end&#xA;&#xA;  // Handle video updates when the duration is changed or a new video starts&#xA;  const updateContent = (i, division, contentIndex, duration) => {&#xA;    const newContent = [...currentContent];&#xA;&#xA;    // Check if we are on the last media item&#xA;    if (contentIndex &#x2B; 1 &lt; division.imageSrcs.length) {&#xA;      // Move to next media if not the last one&#xA;      newContent[i].contentIndex = contentIndex &#x2B; 1;&#xA;    } else {&#xA;      // If this is the last media item, pause here&#xA;      newContent[i].contentIndex = contentIndex; // Keep it at the last item&#xA;      setCurrentContent(newContent);&#xA;&#xA;      // Handle video pause if the last media is a video&#xA;      const mediaElement = videoRefs.current[i];&#xA;      if (mediaElement &amp;&amp; mediaElement.tagName === "VIDEO") {&#xA;        mediaElement.pause();&#xA;        mediaElement.currentTime = mediaElement.duration; // Pause at the end of the video&#xA;      }&#xA;      return; // Exit the function as we don&#x27;t want to loop anymore&#xA;    }&#xA;&#xA;    // Update state to trigger rendering of the next media&#xA;    setCurrentContent(newContent);&#xA;&#xA;    // Handle video playback for the next media item&#xA;    const mediaElement = videoRefs.current[i];&#xA;    if (mediaElement) {&#xA;      mediaElement.pause();&#xA;      mediaElement.currentTime = 0;&#xA;      mediaElement&#xA;        .play()&#xA;        .catch((error) => console.error("Error playing video:", error));&#xA;    }&#xA;  };&#xA;&#xA;  const renderDivision = (division, contentIndex, index) => {&#xA;    const mediaSrc = division.imageSrcs[contentIndex];&#xA;&#xA;    if (!division || !division.imageSrcs || division.imageSrcs.length === 0) {&#xA;      return (&#xA;        &#xA;          <p>No media available</p>&#xA;        &#xA;      );&#xA;    }&#xA;&#xA;    if (!mediaSrc) {&#xA;      return (&#xA;        &#xA;          <p>No media available</p>&#xA;        &#xA;      );&#xA;    }&#xA;&#xA;    if (mediaSrc.endsWith(".mp4")) {&#xA;      return (&#xA;        > (videoRefs.current[index] = el)}&#xA;          src={mediaSrc}&#xA;          autoPlay&#xA;          controls={false}&#xA;          style={{&#xA;            width: "100%",&#xA;            height: "100%",&#xA;            objectFit: "cover",&#xA;            pointerEvents: "none",&#xA;          }}&#xA;          onLoadedData={() => {&#xA;            // Ensure video is properly loaded&#xA;            const mediaElement = videoRefs.current[index];&#xA;            if (mediaElement &amp;&amp; mediaElement.readyState >= 3) {&#xA;              mediaElement.play().catch((error) => {&#xA;                console.error("Error attempting to play the video:", error);&#xA;              });&#xA;            }&#xA;          }}&#xA;        />&#xA;      );&#xA;    } else {&#xA;      return (&#xA;        &#xA;      );&#xA;    }&#xA;  };&#xA;&#xA;  // progress bar code start&#xA;  useEffect(() => {&#xA;    if (totalDuration.current > 0) {&#xA;      // Reset elapsed time at the start&#xA;      setElapsedTime(0);&#xA;&#xA;      const interval = setInterval(() => {&#xA;        setElapsedTime((prevTime) => {&#xA;          // Increment the elapsed time by 1 second if it&#x27;s less than the total time&#xA;          if (prevTime &lt; totalTime) {&#xA;            return prevTime &#x2B; 1;&#xA;          } else {&#xA;            clearInterval(interval); // Clear the interval when totalTime is reached&#xA;            return prevTime;&#xA;          }&#xA;        });&#xA;      }, 1000); // Update every second&#xA;&#xA;      // Clean up the interval on component unmount&#xA;      return () => clearInterval(interval);&#xA;    }&#xA;  }, [totalTime]);&#xA;&#xA;  // progress bar code end&#xA;&#xA;  return (&#xA;    &#xA;      &#xA;        &#xA;          Close&#xA;        &#xA;        <h2>Preview Layout: {layout.name}</h2>&#xA;        &#xA;          {currentContent.map(({ division, contentIndex }, i) => (&#xA;            &#xA;              {renderDivision(division, contentIndex, i)}&#xA;            &#xA;          ))}&#xA;          {/* canvas code for video start */}&#xA;          {/* canvas code for video end */}&#xA;          {/* Progress Bar and Time */}&#xA;          / Background color for progress bar track&#xA;              display: "flex",&#xA;              justifyContent: "space-between",&#xA;              alignItems: "center",&#xA;            }}&#xA;          >&#xA;             totalTime) * 100}%)`,&#xA;                backgroundColor: "#28a745", // Green color for progress bar&#xA;                transition: "width 0.5s linear", // Smooth transition&#xA;              }}&#xA;            >&#xA;&#xA;            {/* Time display */}&#xA;            {/* / Fixed right margin&#xA;                zIndex: 1, // Ensure it&#x27;s above the progress bar&#xA;                padding: "5px",&#xA;                fontSize: "18px",&#xA;                fontWeight: "600",&#xA;                color: "#333",&#xA;                // backgroundColor: "rgba(255, 255, 255, 0.8)", // Add a subtle background for readability&#xA;              }}&#xA;            >&#xA;              {elapsedTime} / {totalTime}s&#xA;             */}&#xA;          &#xA;        &#xA;&#xA;        {/* Download button */}&#xA;        > (e.target.style.backgroundColor = "#218838")}&#xA;          onMouseOut={(e) => (e.target.style.backgroundColor = "#28a745")}&#xA;        >&#xA;          Download Video&#xA;        &#xA;        {/* {recording &amp;&amp; <p>Recording in progress...</p>} */}&#xA;      &#xA;    &#xA;  );&#xA;};&#xA;&#xA;export default Preview;&#xA;&#xA;

    &#xA;

    I tried several methods to record the content of the div with the class "layout," which contains dynamic media elements such as images and videos. The approaches I attempted include :

    &#xA;

    MediaRecorder API : I expected this API to capture the entire div and its contents, but it didn't handle the rendering of all dynamic media elements properly.

    &#xA;

    html2canvas : I used this to capture the layout as a canvas and then attempted to convert it into a video stream. However, it could not capture smooth transitions between media elements, leading to a choppy or incomplete video output.

    &#xA;

    RecordRTC : I integrated RecordRTC to capture the canvas stream of the div. Despite setting up the recorder, the resulting video file either had a 0-byte size or only captured parts of the content inconsistently.

    &#xA;

    FFmpeg and other libraries : I explored these tools hoping they would provide a seamless capture of the dynamic content, but they also failed to capture the full media elements, including videos playing within the layout.

    &#xA;

    In all cases, I expected to get a complete video recording of the div, including all media transitions, but the results were incomplete or not functional.

    &#xA;

    Now, I’m seeking an approach or best practice to record the entire div with its dynamic content and media playback.

    &#xA;

  • ffmpeg change audio encoding and combine audio files

    7 septembre 2024, par Simon

    I asked a question about combining linear16 encoded audio files together here - Combine linear16 encoded audio files | PHP

    &#xA;

    I was suggested to use ffmpeg, I'm new with it, any suggestion how to combine LINEAR16 encoded audio files ?

    &#xA;

    ...&#xA;$client = new TextToSpeechClient();&#xA;$synthesisInputText = new SynthesisInput();&#xA;$audioConfig = new AudioConfig();&#xA;// $audioConfig->setAudioEncoding(AudioEncoding::MP3); works fine&#xA;$audioConfig->setAudioEncoding(AudioEncoding::LINEAR16);&#xA;$voice = new VoiceSelectionParams();&#xA;&#xA;$voice->setLanguageCode(&#x27;en-US&#x27;);&#xA;$voice->setName(&#x27;en-US-Neural2-A&#x27;);&#xA;&#xA;$media_total = &#x27;&#x27;;&#xA;foreach($txt_array as $k => $txt) {&#xA;&#xA;     $synthesisInputText->setText($txt);&#xA;     $response = $client->synthesizeSpeech($synthesisInputText, $voice, $audioConfig);&#xA;     $media = $response->getAudioContent();&#xA;&#xA;     $media_total .= $media; // audio is encoded linear16, and combining in this way does not work&#xA;    &#xA;// how to use ffmpeg here, to combine $media pieces, change encoding&#xA;&#xA;}&#xA;

    &#xA;

    Thanks

    &#xA;

    UPDATE

    &#xA;

    Examples of generated audio files, stored in mp3 file :&#xA;https://storage.googleapis.com/gspeech-audio-storage/gspeech_en-US:6:D:1:0_5c021edd23218122a7ce116cb297bc91_5be04f8b55b1b28025ad6eea55109e83.mp3

    &#xA;

    The audio looks like this. Seems like when making encoding as linear16, the output like the WAV format :

    &#xA;

    5249 4646 240b 0400 5741 5645 666d 7420&#xA;1000 0000 0100 0100 c05d 0000 80bb 0000&#xA;0200 1000 6461 7461 000b 0400 ffff f2ff&#xA;d6ff bcff b7ff c9ff f5ff 2900 5800 7b00&#xA;8800 8b00 8c00 8d00 9000 9400 9100 8800&#xA;7a00 6600 5400 4500 3e00 3b00 3600 3200&#xA;2800 1b00 1000 0a00 0700 0200 f8ff f5ff&#xA;f3ff f8ff ffff 0400 0300 0e00 1b00 0c00&#xA;0800 0500 1000 1500 1e00 2800 2b00 2e00&#xA;2b00 2d00 2900 3000 3300 3200 2f00 2600&#xA;1800 0b00 0200 feff f6ff f7ff f5ff f3ff&#xA;f1ff edff eaff e6ff e1ff d5ff d0ff caff&#xA;c5ff c3ff c2ff c1ff cbff ccff cbff d0ff&#xA;d9ff d7ff ddff ddff e0ff e5ff e2ff f2ff&#xA;f4ff fdff 0200 0100 0600 0a00 1000 0e00&#xA;1300 0f00 0f00 1c00 1a00 2000 2400 2500&#xA;2500 2000 1d00 1800 1300 0f00 1200 0500&#xA;fdff f1ff ecff ddff d3ff cdff b7ff c1ff&#xA;c0ff b8ff b4ff b2ff aaff a8ff a5ff abff&#xA;a6ff a0ff 9bff 91ff 8fff 8aff 86ff 83ff&#xA;84ff 8aff 83ff 78ff 70ff 65ff 66ff 6eff&#xA;71ff 70ff 6fff 69ff 5aff 54ff 4fff 5bff&#xA;5eff 64ff 6eff 68ff 68ff 6aff 6aff 65ff&#xA;71ff 63ff 5aff 54ff 4aff 4eff 56ff 58ff&#xA;66ff 6bff 66ff 66ff 70ff 75ff 6bff 7bff&#xA;71ff 76ff 8bff 98ff 8eff 95ff 9fff 92ff&#xA;93ff 98ff a2ff afff bdff baff b5ff bdff&#xA;b6ff c1ff c0ff c9ff d9ff dfff e7ff f5ff&#xA;f8ff ffff 1000 1200 1200 0a00 0a00 1100&#xA;f7ff 0900 0a00 0300 1300 0e00 1300 1900&#xA;1e00 2600 0400 1700 2000 2600 3200 2f00&#xA;2b00 1c00 2500 1d00 2800 2f00 3200 3d00&#xA;2b00 3c00 3100 4300 4900 4300 5c00 6c00&#xA;6a00 5f00 5e00 4d00 4400 4800 4900 2e00&#xA;3300 3500 3900 3e00 4800 3a00 3600 3a00&#xA;3700 3900 2d00 3800 3800 2700 2500 2000&#xA;2c00 2800 2700 3100 0f00 2100 4200 2f00&#xA;2e00 2400 2c00 2600 1900 2a00 0100 1600&#xA;1d00 2900 4100 4100 6400 5c00 5700 4800&#xA;3e00 3800 1f00 2700 3600 2400 3d00 5200&#xA;6600 6400 6200 4600 4f00 4800 2200 2000&#xA;1f00 2800 0400 2300 1700 2b00 2700 1800&#xA;0000 0000 f0ff e3ff b9ff a6ff acff a3ff&#xA;a2ff 97ff a5ff 96ff 7aff 5cff 56ff 4eff&#xA;31ff 18ff 2aff 1eff 11ff 19ff 04ff 07ff&#xA;08ff e3fe f3fe 1eff e8fe f5fe f1fe cffe&#xA;03ff e2fe 17ff 2bff 11ff 34ff 4fff 4fff&#xA;2dff 4bff 43ff 2eff 60ff 49ff 6cff acff&#xA;e9ff 0b00 5600 3e00 5000 3d00 5b00 5500&#xA;4300 2100 3500 2d00 6200 6800 4b00 5900&#xA;9a00 3a00 5d00 6e00 3200 0400 1400 f8ff&#xA;2900 3200 0700 ebff 0700 f2ff 2800 1100&#xA;1c00 3700 d7ff ddff cdff e3ff f2ff 0e00&#xA;daff 2f00 6900 8f00 a900 7900 6e00 6b00&#xA;f000 e500 7e00 ab00 de00 c700 e000 4801&#xA;3b01 5c01 1901 0701 6c01 e300 f800 4a01&#xA;2901 5a01 5f01 6701 8801 5901 1701 1e01&#xA;4901 3f01 1f01 ff00 5601 cf00 5200 0401&#xA;2e01 7001 2801 4d01 a100 df00 df00 6801&#xA;6401 a100 fa00 ba01 e300 b000 2c01 5501&#xA;b3ff 7e01 5702 3700 f300 6401 f501 3f02&#xA;9dff 98ff 8201 2cff 24fd 6b01 6bff 48ff&#xA;7301 f201 9102 a0ff 3c02 9c00 c500 3901&#xA;5d02 a500 1200 1300 bdfe d8fe 25ff 10fe&#xA;04fd a400 0300 ad01 9e04 6105 1405 ee04&#xA;fe04 8a05 4606 2f05 5702 fa02 1901 b002&#xA;4cff 8b01 9902 6a03 0d04 2e05 f202 3801&#xA;9000 d4fe 0c00 2501 56ff 41ff 31ff 98fd&#xA;d0fd a7fb 3efe 45ff 91fc c9fe 3cfd 21fc&#xA;b5fd 2bfd 7bfb 0afd 14ff f1fe 95ff 18ff&#xA;0000 50fd 59fe a000 f9ff 7a00 8100 1100&#xA;f0ff 5300 af00 1f00 3a03 e001 7703 2e03&#xA;9503 5001 8fff b400 c9ff 1602 d201 3e00&#xA;2201 9501 88ff 71ff f901 5100 4eff 1b00&#xA;7e00 aefe e6fd 24fd 27fc d2fe 47fd d5fe&#xA;befe ddfd 22ff 03fe c7fc 5dfe c2fd f2fb&#xA;aefe 45fd 63fd 16fb 82fd ecfc 5ffc 66fd&#xA;3cfe fcfd 4cfd 21fe f2fd 3bfd 0afd f8fc&#xA;74fd bafe 36fd 6bff 65fe c2fd c0fd e8fe&#xA;cbff 1dff dcff 26ff 3afe 92fd 06fd 49fe&#xA;78fb 30fe 8bff dafe bcff 37ff 50fe a3fe&#xA;69fe 7dfe 5e00 06ff 1900 4afd 93fd 09ff&#xA;0eff d5fd a900 d702 0300 a301 2903 2fff&#xA;07ff d6fd 51fe 9aff 8dff 3200 4a01 e200&#xA;cdff 5201 d501 fd01 bd00 6001 ab00 c6fd&#xA;20ff ccff c0fc 6eff c400 44ff 8001 24ff&#xA;3bff 0800 93fd 9500 bffe 9dfe c8fe dafd&#xA;5ffe 76fe e6ff 8bfe 8500 6001 73ff a200&#xA;d2fe fdfe 1bff 60ff cb00 1800 1d01 7e00&#xA;f800 c600 ec00 9e01 c101 f601 8701 ff01&#xA;fb01 d400 bc00 b300 5c00 9100 eeff 6e01&#xA;6c02 3eff b0ff 1101 7bff d8ff 9c00 6ffe&#xA;1fff aafd a0fe d8fd b5fe 5cfd 36fc 31ff&#xA;24fe 71ff 23fe 60ff 65fd 20fd 5efd 9efb&#xA;7bfe 07fc 3ffc c1fe ecfc c1fb bcfb ebfc&#xA;6afd d1fd 9cff 8dfe 82fd cffd 4dfc 53fd&#xA;6cfd 82fe a1fd 52fd f8fe 6ffd 39fd e8fc&#xA;b7fb 23fd 2dfd aefc aefc bffc 75fc f0fa&#xA;f5fc e8fd 76fe 2dfd 9afc 80fd 1bfc a8fa&#xA;36fd 35fa d8f9 31fa d1fa f8fb a2fc e7fd&#xA;52fd d0fe d9ff 2eff 97ff 41ff 23fd 22fe&#xA;73fd 88fd 78ff 9aff e2fe 0802 e203 b203&#xA;0b04 6104 9303 1903 d701 4704 b905 0903&#xA;d103 5805 3006 0706 7707 4a07 9607 e907&#xA;d606 b906 1f08 ee04 1a04 1507 3d08 ff08&#xA;ce09 740a a609 5109 ff08 fd08 a708 e507&#xA;1e08 2e07 7208 4e08 9807 3009 6808 d408&#xA;c00a 250a f308 6807 4806 5c05 0904 2206&#xA;6e06 8707 c208 3c08 8e0a 7e09 fc07 7708&#xA;d406 d205 6405 6d04 7e04 6604 7704 7005&#xA;7707 2107 1a06 9b05 ab03 5901 47fe 75fd&#xA;28fc 84fa 87fb 21fc d4fb 77f9 41f9 98f8&#xA;57f7 2bf6 7af4 64f2 7cee 29ec 05ea 9ee8&#xA;90e9 0aea d2ea b6eb efeb 77e9 e0e6 85e6&#xA;59e4 5fe4 89e6 cee8 10ea 5eeb 5aee 66ef&#xA;49f2 4cf7 3ffa 91fb befd 75fd 8ffd 32fd&#xA;9eff 0202 8806 7a07 c90d ca15 b913 5614&#xA;7a16 7e16 a515 c617 2c17 c815 8b13 ef0f&#xA;9512 4f13 0212 5313 c413 0511 5810 cf0d&#xA;f907 8704 6b01 47fd 7afb 8bfb a9f8 25f8&#xA;0ef7 acf5 1cf5 83f3 fff2 53f0 c4ed 7ceb&#xA;76eb 14e9 eee8 f8e9 cfeb 1ded 89ef dff2&#xA;fcf3 caf4 bff4 0df6 b7f6 57f7 89f9 56fc&#xA;bafe 6702 c705 2609 ee0b 480e 5610 c512&#xA;9713 1614 9015 9d16 da16 e417 ad19 831a&#xA;cb1b 541d 421e 341e 5f1d 701b 1419 c117&#xA;e615 6b15 af15 b714 6e13 fe13 3112 1d11&#xA;be0f 130c 430a 4d08 9305 0d03 4402 9cff&#xA;4ffd 1efe 9dfd 73fc 8efa 49f9 76f7 e3f3&#xA;3bf1 19f0 fded ebeb daec edec c4eb bdea&#xA;ace9 b4e7 b7e5 73e4 f8e2 f3e1 d3e0 fadf&#xA;35df 77e0 c6e1 84e2 f3e2 14e2 04e1 03df&#xA;49dc 7bdc 61db a2dc dde4 99ed fef1 1bf9&#xA;93fc 76f9 11fa 3c01 df02 ce04 2c07 f106&#xA;8f09 9b07 470a 4d0f 5213 b817 6d20 5a23&#xA;...&#xA;

    &#xA;

    And when the encoding is set to mp3, it looks like this :

    &#xA;

    fff3 84c4 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;0000 0000 0000 0000 0000 0000 0000 0000&#xA;...&#xA;

    &#xA;

    It seems like the linear16 file, which can be repeated one after another, and it works fine.

    &#xA;

    I was trying to convert audio1 format to audio2 in native php by making a byte analyze, but the result was broken, and not be readable.

    &#xA;

  • Java uses FFmpegRecoder to encode frames into H264 streams

    5 septembre 2024, par zhang1973

    I want to obtain the Frame from the video stream, process it, use FFmpegRecoder to encode it into an H264 stream, and transmit it to the front-end. But I found that the AVPacket obtained directly using grabber.grabAVPacket can be converted into H264 stream and played normally. The H264 stream encoded using FFmpegRecoder cannot be played.

    &#xA;

    Here is my Code :

    &#xA;

        private FFmpegFrameRecorder recorder;&#xA;    private ByteArrayOutputStream outputStream =  new ByteArrayOutputStream();;&#xA;    private boolean createRecoder(Frame frame){&#xA;        recorder = new FFmpegFrameRecorder(outputStream, frame.imageWidth, frame.imageHeight);&#xA;        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);&#xA;        recorder.setFormat("h264");  //"h264"); //&#xA;        recorder.setFrameRate(30);&#xA;        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);&#xA;        recorder.setVideoBitrate(4000 * 1000); // 设置比特率为4000 kbps&#xA;        recorder.setVideoOption("preset", "ultrafast"); // 设置编码器预设,"ultrafast"是最快的,"veryslow"是最慢但质量最好&#xA;        recorder.setAudioChannels(0);&#xA;&#xA;        try {&#xA;            recorder.start();&#xA;            return recorderStatus = true;&#xA;        } catch (org.bytedeco.javacv.FrameRecorder.Exception e1) {&#xA;            log.info("启动转码录制器失败", e1);&#xA;            MediaService.cameras.remove(cameraDto.getMediaKey());&#xA;            e1.printStackTrace();&#xA;        }&#xA;&#xA;        return recorderStatus = false;&#xA;    }&#xA;&#xA;    private boolean slow = false;&#xA;    protected void transferStream2H264() throws FFmpegFrameGrabber.Exception {&#xA;&#xA;        // 初始化和拉去图像的方法&#xA;        log.info(" create grabber  ");&#xA;        if (!createGrabber()) {&#xA;            log.error("   == > ");&#xA;            return;&#xA;        }&#xA;        transferFlag = true;&#xA;&#xA;        if(!createRecoder(grabber.grab())){&#xA;            return;&#xA;        }&#xA;&#xA;        try {&#xA;            grabber.flush();&#xA;        } catch (Exception e) {&#xA;            log.info("清空拉流器缓存失败", e);&#xA;            e.printStackTrace();&#xA;        }&#xA;&#xA;        if (header == null) {&#xA;            header = bos.toByteArray();&#xA;            slow = true;&#xA;//          System.out.println("Header1");&#xA;//          System.out.println(header);&#xA;            bos.reset();&#xA;        }else{&#xA;            System.out.println("Header2");&#xA;            System.out.println(header);&#xA;        }&#xA;&#xA;        running = true;&#xA;&#xA;        // 事实更新所有的连接数&#xA;        listenClient();&#xA;&#xA;        long startTime = 0;&#xA;        long videoTS = 0;&#xA;&#xA;        for (; running &amp;&amp; grabberStatus;) {&#xA;            try {&#xA;                if (transferFlag) {&#xA;                    long startGrab = System.currentTimeMillis();&#xA;                    //视频采集器&#xA;//                  AVPacket pkt = grabber.grabPacket();&#xA;                    Frame frame = grabber.grab();&#xA;                    recorder.record(frame);&#xA;                    byte[] videoData = outputStream.toByteArray();&#xA;                    if ((System.currentTimeMillis() - startGrab) > 5000) {&#xA;                        log.info("\r\n{}\r\n视频流网络异常>>>", cameraDto.getUrl());&#xA;                        closeMedia();&#xA;                        break;&#xA;                    }&#xA;&#xA;                        videoTS = 1000 * (System.currentTimeMillis() - startTime);&#xA;&#xA;&#xA;                            if (startTime == 0) {&#xA;                                startTime = System.currentTimeMillis();&#xA;                            }&#xA;                            videoTS = 1000 * (System.currentTimeMillis() - startTime);&#xA;&#xA;                                byte[] rbuffer = videoData;&#xA;                                readSize = videoData.length;&#xA;&#xA;                                if(spsdata == null || ppsdata == null){&#xA;                                    movePos = 0;&#xA;                                    lastPos = 0;&#xA;                                    isNewPack = true;&#xA;                                    while(movePos &lt; readSize){&#xA;                                        if (rbuffer[movePos] == 0 &amp;&amp; rbuffer[movePos &#x2B; 1] == 0 &amp;&amp; rbuffer[movePos &#x2B; 2] == 1) {&#xA;                                            findCode = true;&#xA;                                            skipLen = 3;&#xA;                                            mCurFrameFirstByte = (int)(0xff &amp; rbuffer[movePos &#x2B; skipLen]);&#xA;                                        } else if (rbuffer[movePos] == 0 &amp;&amp; rbuffer[movePos &#x2B; 1] == 0 &amp;&amp; rbuffer[movePos &#x2B; 2] == 0 &amp;&amp; rbuffer[movePos &#x2B; 3] == 1) {&#xA;                                            findCode = true;&#xA;                                            skipLen = 4;&#xA;                                            mCurFrameFirstByte = (int)(0xff &amp; rbuffer[movePos &#x2B; skipLen]);&#xA;                                        } else {&#xA;                                            skipLen = 1;&#xA;                                        }&#xA;&#xA;                                        if(!isFirstFind &amp;&amp; isNewPack &amp;&amp; findCode){&#xA;                                            mFrameFirstByte = mCurFrameFirstByte;&#xA;                                            findCode = false;&#xA;                                            isNewPack = false;&#xA;                                            mNaluType          = mFrameFirstByte &amp; 0x1f;&#xA;                                            if(mNaluType != MediaConstant.NALU_TYPE_SEI &amp;&amp;&#xA;                                                    mNaluType != MediaConstant.NALU_TYPE_SPS &amp;&amp;&#xA;                                                    mNaluType != MediaConstant.NALU_TYPE_PPS &amp;&amp;&#xA;                                                    mNaluType != MediaConstant.NALU_TYPE_IDR){&#xA;                                                startCounter&#x2B;&#x2B;;&#xA;                                                break;&#xA;                                            }&#xA;                                        }&#xA;&#xA;                                        if(isFirstFind){&#xA;                                            isFirstFind = false;&#xA;                                            findCode = false;&#xA;                                            mFrameFirstByte = mCurFrameFirstByte;&#xA;                                        }&#xA;&#xA;                                        if(findCode){&#xA;                                            startCounter&#x2B;&#x2B;;&#xA;                                            mNaluType          = mFrameFirstByte &amp; 0x1f;&#xA;&#xA;                                            findCode = false;&#xA;                                            mFrameLen = (movePos - lastPos);&#xA;                                            if(mNaluType == MediaConstant.NALU_TYPE_IDR){&#xA;                                                mFrameLen = readSize - movePos;&#xA;                                            }&#xA;&#xA;                                            if(mNaluType != MediaConstant.NALU_TYPE_SEI &amp;&amp;&#xA;                                                    mNaluType != MediaConstant.NALU_TYPE_SPS &amp;&amp;&#xA;                                                    mNaluType != MediaConstant.NALU_TYPE_PPS &amp;&amp;&#xA;                                                    mNaluType != MediaConstant.NALU_TYPE_IDR){&#xA;                                                System.out.println("  one packe many frames --->  type: " &#x2B; mNaluType &#x2B; " jump out ");&#xA;                                                break;&#xA;                                            }&#xA;                                            if(mNaluType == MediaConstant.NALU_TYPE_SPS){&#xA;                                                if(null == spsdata){&#xA;                                                    spsdata = new byte[mFrameLen];&#xA;                                                    System.arraycopy(rbuffer, lastPos, spsdata, 0, mFrameLen);&#xA;                                                }&#xA;                                            }&#xA;                                            if(mNaluType == MediaConstant.NALU_TYPE_PPS){&#xA;&#xA;                                                if(null == ppsdata){&#xA;                                                    ppsdata = new byte[mFrameLen];&#xA;                                                    System.arraycopy(rbuffer, lastPos, ppsdata, 0, mFrameLen);&#xA;                                                }&#xA;                                            }&#xA;&#xA;                                            lastPos = movePos;&#xA;                                            mFrameFirstByte = mCurFrameFirstByte;&#xA;                                            mNaluType          = mFrameFirstByte &amp; 0x1f;&#xA;                                            if(mNaluType == MediaConstant.NALU_TYPE_IDR){&#xA;                                                mFrameLen = readSize - movePos;&#xA;                                                startCounter&#x2B;&#x2B;;&#xA;&#xA;                                                break;&#xA;                                            }&#xA;                                        }&#xA;&#xA;                                        movePos &#x2B;= skipLen;&#xA;                                        isNewPack = false;&#xA;                                    }&#xA;                                }&#xA;&#xA;                                sendFrameData(rbuffer);&#xA;//                          }&#xA;//                          av_packet_unref(pkt);&#xA;//                      }&#xA;&#xA;//                  }&#xA;                } else {&#xA;                }&#xA;            } catch (Exception e) {&#xA;                grabberStatus = false;&#xA;                MediaService.cameras.remove(cameraDto.getMediaKey());&#xA;            } catch (FFmpegFrameRecorder.Exception e) {&#xA;                throw new RuntimeException(e);&#xA;            }&#xA;        }&#xA;&#xA;        try {&#xA;            grabber.close();&#xA;            bos.close();&#xA;        } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {&#xA;            e.printStackTrace();&#xA;        } catch (Exception e) {&#xA;            e.printStackTrace();&#xA;        } catch (IOException e) {&#xA;            e.printStackTrace();&#xA;        } finally {&#xA;            closeMedia();&#xA;        }&#xA;        log.info("关闭媒体流-javacv,{} ", cameraDto.getUrl());&#xA;    }&#xA;

    &#xA;