Recherche avancée

Médias (2)

Mot : - Tags -/media

Autres articles (43)

  • Submit enhancements and plugins

    13 avril 2011

    If you have developed a new extension to add one or more useful features to MediaSPIP, let us know and its integration into the core MedisSPIP functionality will be considered.
    You can use the development discussion list to request for help with creating a plugin. As MediaSPIP is based on SPIP - or you can use the SPIP discussion list SPIP-Zone.

  • Les autorisations surchargées par les plugins

    27 avril 2010, par

    Mediaspip core
    autoriser_auteur_modifier() afin que les visiteurs soient capables de modifier leurs informations sur la page d’auteurs

  • Librairies et binaires spécifiques au traitement vidéo et sonore

    31 janvier 2010, par

    Les logiciels et librairies suivantes sont utilisées par SPIPmotion d’une manière ou d’une autre.
    Binaires obligatoires FFMpeg : encodeur principal, permet de transcoder presque tous les types de fichiers vidéo et sonores dans les formats lisibles sur Internet. CF ce tutoriel pour son installation ; Oggz-tools : outils d’inspection de fichiers ogg ; Mediainfo : récupération d’informations depuis la plupart des formats vidéos et sonores ;
    Binaires complémentaires et facultatifs flvtool2 : (...)

Sur d’autres sites (5689)

  • Cannot concatenate videos ffmpeg [on hold]

    1er mai 2014, par Paul Prescod

    I have a bitmap that I would like to concatenate to the front of many videos as a sort of title screen or disclaimer screen.

    I try to turn it into a video with the same attributes as the rest of the video. So first I introspect the video :

    ffmpeg version 2.2.1 Copyright (c) 2000-2014 the FFmpeg developers
     built on Apr 11 2014 22:50:38 with Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
     configuration: --prefix=/usr/local/Cellar/ffmpeg/2.2.1 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --enable-avresample --enable-vda --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libfaac --enable-libmp3lame --enable-libxvid
     libavutil      52. 66.100 / 52. 66.100
     libavcodec     55. 52.102 / 55. 52.102
     libavformat    55. 33.100 / 55. 33.100
     libavdevice    55. 10.100 / 55. 10.100
     libavfilter     4.  2.100 /  4.  2.100
     libavresample   1.  2.  0 /  1.  2.  0
     libswscale      2.  5.102 /  2.  5.102
     libswresample   0. 18.100 /  0. 18.100
     libpostproc    52.  3.100 / 52.  3.100
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'EO1.mp4':
     Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.78.3
     Duration: 00:00:17.77, start: 0.000000, bitrate: 582 kb/s
    Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 584x328 [SAR 1:1 DAR 73:41], 512 kb/s, 23.98 fps, 23.98 tbr, 1199 tbn, 47.96 tbc (default)
    Metadata:
     creation_time   : 1970-01-01 00:00:00
     handler_name    : VideoHandler
    Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 64 kb/s (default)
    Metadata:
     creation_time   : 1970-01-01 00:00:00
     handler_name    : SoundHandler

    Then I try and create a similar file :

    /usr/local/Cellar/ffmpeg/2.2.1/bin/ffmpeg -y -loop 1 -i Disclaimer.png -c:v libx264 -r 23.98 -t 5 -pix_fmt yuv420p -profile:v main disclaimer.mp4

    It seems to work okay. The video plays I would expect it to. The attributes turn out very similar. Here is a diff :

    < Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'disclaimer.mp4':
    ---
    > Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'EO1.mp4':
    18,20c18,21
    <     encoder         : Lavf55.33.100
    <   Duration: 00:00:05.01, start: 0.000000, bitrate: 21 kb/s
    <     Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 584x328 [SAR 1:1 DAR 73:41], 17 kb/s, 23.98 fps, 23.98 tbr, 19184 tbn, 47.96 tbc (default)
    ---
    >     creation_time   : 1970-01-01 00:00:00
    >     encoder         : Lavf52.78.3
    >   Duration: 00:00:17.77, start: 0.000000, bitrate: 582 kb/s
    >     Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 584x328 [SAR 1:1 DAR 73:41], 512 kb/s, 23.98 fps, 23.98 tbr, 1199 tbn, 47.96 tbc (default)
    21a23
    22a25,28
    >     Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 64 kb/s (default)
    >     Metadata:
    >       handler_name    : SoundHandler

    But when I try to concatenate, I get errors.

    > $ cat temporary.txt

       file disclaimer.mp4
       file EO1.mp4

    /usr/local/Cellar/ffmpeg/2.2.1/bin/ffmpeg -y -f concat -i temporary.txt -c copy output.mp4

    [concat @ 0x7fd880806600] Estimating duration from bitrate, this may be inaccurate
    Input #0, concat, from 'temporary.txt':
     Duration: 00:00:00.02, start: 0.000000, bitrate: 17 kb/s
    Stream #0:0: Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 584x328 [SAR 1:1 DAR 73:41], 17 kb/s, 23.98 fps, 23.98 tbr, 19184 tbn, 47.96 tbc
    Output #0, mp4, to 'output.mp4':
     Metadata:
    encoder         : Lavf55.33.100
    Stream #0:0: Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 584x328 [SAR 1:1 DAR 73:41], q=2-31, 17 kb/s, 23.98 fps, 19184 tbn, 19184 tbc
    Stream mapping:
     Stream #0:0 -> #0:0 (copy)
    Press [q] to stop, [?] for help
    [mp4 @ 0x7fd880829a00] Non-monotonous DTS in output stream 0:0; previous: 93600, current: 5951; changing to 93601. This may result in incorrect timestamps in the output file.
    [concat @ 0x7fd880806600] Invalid stream index 1
    [mp4 @ 0x7fd880829a00] Non-monotonous DTS in output stream 0:0; previous: 93601, current: 6001; changing to 93602. This may result in incorrect timestamps in the output file.
    [concat @ 0x7fd880806600] Invalid stream index 1
    [mp4 @ 0x7fd880829a00] Non-monotonous DTS in output stream 0:0; previous: 93602, current: 6051; changing to 93603. This may result in incorrect timestamps in the output file.

    ...

    frame=  546 fps=0.0 q=-1.0 Lsize=    1127kB time=00:00:04.90 bitrate=1882.9kbits/s    
    video:1123kB audio:0kB subtitle:0 data:0 global headers:0kB muxing overhead 0.349865%

    The output looks like it only has my disclaimer file in it, not the rest of the video.

    I’m also confused why it feels like it needs to "estimate" anything. It knows the input FPS and input durations. I’m not sure if this is the problem or not. Maybe its just a bug.

  • Merged Video Contains Inverted Clips After First Video Ends

    3 février, par Nikunj Agrawal

    I am working on a Flutter application that merges multiple videos using ffmpeg_kit_flutter . However, after merging, I notice that the second video (and any subsequent ones) appear inverted or rotated in the final output.

    


    Issue Details :

    


      

    1. The first video appears normal.
    2. 


    3. The videos can be recorded using both front and back cameras.
    4. 


    5. The second (and later) videos are flipped or rotated upside down.
    6. 


    7. This happens after merging using ffmpeg_kit_flutter.
    8. 


    


    Question :
How can I correctly merge multiple videos in Flutter without rotation issues ? Is there a way to normalize video orientation before merging using ffmpeg_kit_flutter ?

    


    Any help would be appreciated ! 🚀

    


    Code :

    


    import &#x27;dart:io&#x27;;&#xA;import &#x27;dart:math&#x27;;&#xA;&#xA;import &#x27;package:camera/camera.dart&#x27;;&#xA;import &#x27;package:ffmpeg_kit_flutter/ffmpeg_kit.dart&#x27;;&#xA;import &#x27;package:ffmpeg_kit_flutter/return_code.dart&#x27;;&#xA;import &#x27;package:flutter/material.dart&#x27;;&#xA;import &#x27;package:path_provider/path_provider.dart&#x27;;&#xA;import &#x27;package:permission_handler/permission_handler.dart&#x27;;&#xA;import &#x27;package:record/record.dart&#x27;;&#xA;import &#x27;package:videotest/video_player.dart&#x27;;&#xA;&#xA;class MergeVideoRecording extends StatefulWidget {&#xA;  const MergeVideoRecording({super.key});&#xA;&#xA;  @override&#xA;  State<mergevideorecording> createState() => _MergeVideoRecordingState();&#xA;}&#xA;&#xA;class _MergeVideoRecordingState extends State<mergevideorecording> {&#xA;  CameraController? _cameraController;&#xA;  final AudioRecorder _audioRecorder = AudioRecorder();&#xA;&#xA;  bool _isRecording = false;&#xA;  String? _videoPath;&#xA;  String? _audioPath;&#xA;  List<cameradescription> _cameras = [];&#xA;  int _currentCameraIndex = 0;&#xA;  final List<string> _recordedVideos = [];&#xA;&#xA;  @override&#xA;  Widget build(BuildContext context) {&#xA;    return Scaffold(&#xA;      body: Column(&#xA;        mainAxisAlignment: MainAxisAlignment.center,&#xA;        children: [&#xA;          _cameraController != null &amp;&amp; _cameraController!.value.isInitialized&#xA;              ? SizedBox(&#xA;                  width: MediaQuery.of(context).size.width * 0.4,&#xA;                  height: MediaQuery.of(context).size.height * 0.3,&#xA;                  child: Stack(&#xA;                    children: [&#xA;                      ClipRRect(&#xA;                        borderRadius: BorderRadius.circular(16),&#xA;                        child: SizedBox(&#xA;                          width: MediaQuery.of(context).size.width * 0.4,&#xA;                          height: MediaQuery.of(context).size.height * 0.3,&#xA;                          child: Transform(&#xA;                            alignment: Alignment.center,&#xA;                            transform:&#xA;                                _cameras[_currentCameraIndex].lensDirection ==&#xA;                                        CameraLensDirection.front&#xA;                                    ? Matrix4.rotationY(pi)&#xA;                                    : Matrix4.identity(),&#xA;                            child: CameraPreview(_cameraController!),&#xA;                          ),&#xA;                        ),&#xA;                      ),&#xA;                      Align(&#xA;                        alignment: Alignment.topRight,&#xA;                        child: InkWell(&#xA;                          onTap: _switchCamera,&#xA;                          child: const Padding(&#xA;                            padding: EdgeInsets.all(8.0),&#xA;                            child: CircleAvatar(&#xA;                              radius: 18,&#xA;                              backgroundColor: Colors.white,&#xA;                              child: Icon(&#xA;                                Icons.flip_camera_android,&#xA;                                color: Colors.black,&#xA;                              ),&#xA;                            ),&#xA;                          ),&#xA;                        ),&#xA;                      ),&#xA;                    ],&#xA;                  ),&#xA;                )&#xA;              : const CircularProgressIndicator(),&#xA;          const SizedBox(height: 16),&#xA;          Row(&#xA;            mainAxisAlignment: MainAxisAlignment.center,&#xA;            children: [&#xA;              FloatingActionButton(&#xA;                heroTag: &#x27;record_button&#x27;,&#xA;                onPressed: _toggleRecording,&#xA;                child: Icon(&#xA;                  _isRecording ? Icons.stop : Icons.video_camera_back,&#xA;                ),&#xA;              ),&#xA;              const SizedBox(&#xA;                width: 50,&#xA;              ),&#xA;              FloatingActionButton(&#xA;                heroTag: &#x27;merge_button&#x27;,&#xA;                onPressed: _mergeVideos,&#xA;                child: const Icon(&#xA;                  Icons.merge,&#xA;                ),&#xA;              ),&#xA;            ],&#xA;          ),&#xA;          if (!_isRecording)&#xA;            ListView.builder(&#xA;              shrinkWrap: true,&#xA;              itemCount: _recordedVideos.length,&#xA;              itemBuilder: (context, index) => InkWell(&#xA;                onTap: () {&#xA;                  Navigator.push(&#xA;                    context,&#xA;                    MaterialPageRoute(&#xA;                      builder: (context) => VideoPlayerScreen(&#xA;                        videoPath: _recordedVideos[index],&#xA;                      ),&#xA;                    ),&#xA;                  );&#xA;                },&#xA;                child: ListTile(&#xA;                  title: Text(&#x27;Video ${index &#x2B; 1}&#x27;),&#xA;                  subtitle: Text(&#x27;Path ${_recordedVideos[index]}&#x27;),&#xA;                  trailing: const Icon(Icons.play_arrow),&#xA;                ),&#xA;              ),&#xA;            ),&#xA;        ],&#xA;      ),&#xA;    );&#xA;  }&#xA;&#xA;  @override&#xA;  void dispose() {&#xA;    _cameraController?.dispose();&#xA;    _audioRecorder.dispose();&#xA;    super.dispose();&#xA;  }&#xA;&#xA;  @override&#xA;  void initState() {&#xA;    super.initState();&#xA;    _initializeDevices();&#xA;  }&#xA;&#xA;  Future<void> _initializeCameraController(CameraDescription camera) async {&#xA;    _cameraController = CameraController(&#xA;      camera,&#xA;      ResolutionPreset.high,&#xA;      enableAudio: true,&#xA;      imageFormatGroup: ImageFormatGroup.yuv420, // Add this line&#xA;    );&#xA;&#xA;    await _cameraController!.initialize();&#xA;    await _cameraController!.setExposureMode(ExposureMode.auto);&#xA;    await _cameraController!.setFocusMode(FocusMode.auto);&#xA;    setState(() {});&#xA;  }&#xA;&#xA;  Future<void> _initializeDevices() async {&#xA;    final cameraStatus = await Permission.camera.request();&#xA;    final micStatus = await Permission.microphone.request();&#xA;&#xA;    if (!cameraStatus.isGranted || !micStatus.isGranted) {&#xA;      _showError(&#x27;Camera and microphone permissions required&#x27;);&#xA;      return;&#xA;    }&#xA;&#xA;    _cameras = await availableCameras();&#xA;    if (_cameras.isNotEmpty) {&#xA;      final frontCameraIndex = _cameras.indexWhere(&#xA;          (camera) => camera.lensDirection == CameraLensDirection.front);&#xA;      _currentCameraIndex = frontCameraIndex != -1 ? frontCameraIndex : 0;&#xA;      await _initializeCameraController(_cameras[_currentCameraIndex]);&#xA;    }&#xA;  }&#xA;&#xA;  // Merge video&#xA;  Future<void> _mergeVideos() async {&#xA;    if (_recordedVideos.isEmpty) {&#xA;      _showError(&#x27;No videos to merge&#x27;);&#xA;      return;&#xA;    }&#xA;&#xA;    try {&#xA;      // Debug logging&#xA;      print(&#x27;Starting merge process&#x27;);&#xA;      print(&#x27;Number of videos to merge: ${_recordedVideos.length}&#x27;);&#xA;      for (var i = 0; i &lt; _recordedVideos.length; i&#x2B;&#x2B;) {&#xA;        final file = File(_recordedVideos[i]);&#xA;        final exists = await file.exists();&#xA;        final size = exists ? await file.length() : 0;&#xA;        print(&#x27;Video $i: ${_recordedVideos[i]}&#x27;);&#xA;        print(&#x27;Exists: $exists, Size: $size bytes&#x27;);&#xA;      }&#xA;&#xA;      final Directory appDir = await getApplicationDocumentsDirectory();&#xA;      final String outputPath =&#xA;          &#x27;${appDir.path}/merged_${DateTime.now().millisecondsSinceEpoch}.mp4&#x27;;&#xA;      final String listFilePath = &#x27;${appDir.path}/list.txt&#x27;;&#xA;&#xA;      print(&#x27;Output path: $outputPath&#x27;);&#xA;      print(&#x27;List file path: $listFilePath&#x27;);&#xA;&#xA;      // Create and verify list file&#xA;      final listFile = File(listFilePath);&#xA;      final fileContent = _recordedVideos&#xA;          .map((path) => "file &#x27;${path.replaceAll("&#x27;", "&#x27;\\&#x27;&#x27;")}&#x27;")&#xA;          .join(&#x27;\n&#x27;);&#xA;      await listFile.writeAsString(fileContent);&#xA;&#xA;      print(&#x27;List file content:&#x27;);&#xA;      print(await listFile.readAsString());&#xA;&#xA;      // Simpler FFmpeg command for testing&#xA;      final command = &#x27;&#x27;&#x27;&#xA;      -f concat&#xA;      -safe 0&#xA;      -i "$listFilePath"&#xA;      -c copy&#xA;      -y&#xA;      "$outputPath"&#xA;    &#x27;&#x27;&#x27;&#xA;          .trim()&#xA;          .replaceAll(&#x27;\n&#x27;, &#x27; &#x27;);&#xA;&#xA;      print(&#x27;Executing FFmpeg command: $command&#x27;);&#xA;&#xA;      final session = await FFmpegKit.execute(command);&#xA;      final returnCode = await session.getReturnCode();&#xA;      final logs = await session.getAllLogsAsString();&#xA;      final failStackTrace = await session.getFailStackTrace();&#xA;&#xA;      print(&#x27;FFmpeg return code: ${returnCode?.getValue() ?? "null"}&#x27;);&#xA;      print(&#x27;FFmpeg logs: $logs&#x27;);&#xA;      if (failStackTrace != null) {&#xA;        print(&#x27;FFmpeg fail stack trace: $failStackTrace&#x27;);&#xA;      }&#xA;&#xA;      if (ReturnCode.isSuccess(returnCode)) {&#xA;        final outputFile = File(outputPath);&#xA;        final outputExists = await outputFile.exists();&#xA;        final outputSize = outputExists ? await outputFile.length() : 0;&#xA;&#xA;        print(&#x27;Output file exists: $outputExists&#x27;);&#xA;        print(&#x27;Output file size: $outputSize bytes&#x27;);&#xA;&#xA;        if (outputExists &amp;&amp; outputSize > 0) {&#xA;          setState(() => _recordedVideos.add(outputPath));&#xA;          _showSuccess(&#x27;Videos merged successfully&#x27;);&#xA;        } else {&#xA;          _showError(&#x27;Merged file is empty or not created&#x27;);&#xA;        }&#xA;      } else {&#xA;        _showError(&#x27;Failed to merge videos. Check logs for details.&#x27;);&#xA;      }&#xA;&#xA;      // Clean up&#xA;      try {&#xA;        await listFile.delete();&#xA;        print(&#x27;List file cleaned up successfully&#x27;);&#xA;      } catch (e) {&#xA;        print(&#x27;Failed to delete list file: $e&#x27;);&#xA;      }&#xA;    } catch (e, s) {&#xA;      print(&#x27;Error during merge: $e&#x27;);&#xA;      print(&#x27;Stack trace: $s&#x27;);&#xA;      _showError(&#x27;Error merging videos: ${e.toString()}&#x27;);&#xA;    }&#xA;  }&#xA;&#xA;  void _showError(String message) {&#xA;    ScaffoldMessenger.of(context).showSnackBar(&#xA;      SnackBar(content: Text(message), backgroundColor: Colors.red),&#xA;    );&#xA;  }&#xA;&#xA;  void _showSuccess(String message) {&#xA;    ScaffoldMessenger.of(context).showSnackBar(&#xA;      SnackBar(content: Text(message), backgroundColor: Colors.green),&#xA;    );&#xA;  }&#xA;&#xA;  Future<void> _startAudioRecording() async {&#xA;    try {&#xA;      final Directory tempDir = await getTemporaryDirectory();&#xA;      final audioPath = &#x27;${tempDir.path}/recording.wav&#x27;;&#xA;      await _audioRecorder.start(const RecordConfig(), path: audioPath);&#xA;      setState(() => _isRecording = true);&#xA;    } catch (e) {&#xA;      _showError(&#x27;Recording start error: $e&#x27;);&#xA;    }&#xA;  }&#xA;&#xA;  Future<void> _startVideoRecording() async {&#xA;    try {&#xA;      await _cameraController!.startVideoRecording();&#xA;      setState(() => _isRecording = true);&#xA;    } catch (e) {&#xA;      _showError(&#x27;Recording start error: $e&#x27;);&#xA;    }&#xA;  }&#xA;&#xA;  Future<void> _stopAndSaveAudioRecording() async {&#xA;    _audioPath = await _audioRecorder.stop();&#xA;    if (_audioPath != null) {&#xA;      final Directory appDir = await getApplicationDocumentsDirectory();&#xA;      final timestamp = DateTime.now().millisecondsSinceEpoch;&#xA;      final String audioFileName = &#x27;audio_$timestamp.wav&#x27;;&#xA;      await File(_audioPath!).copy(&#x27;${appDir.path}/$audioFileName&#x27;);&#xA;      _showSuccess(&#x27;Saved: $audioFileName&#x27;);&#xA;    }&#xA;  }&#xA;&#xA;  Future<void> _stopAndSaveVideoRecording() async {&#xA;    try {&#xA;      final video = await _cameraController!.stopVideoRecording();&#xA;      _videoPath = video.path;&#xA;&#xA;      if (_videoPath != null) {&#xA;        final Directory appDir = await getApplicationDocumentsDirectory();&#xA;        final timestamp = DateTime.now().millisecondsSinceEpoch;&#xA;        final String videoFileName = &#x27;video_$timestamp.mp4&#x27;;&#xA;        final savedVideoPath = &#x27;${appDir.path}/$videoFileName&#x27;;&#xA;        await File(_videoPath!).copy(savedVideoPath);&#xA;&#xA;        setState(() {&#xA;          _recordedVideos.add(savedVideoPath);&#xA;          _isRecording = false;&#xA;        });&#xA;&#xA;        _showSuccess(&#x27;Saved: $videoFileName&#x27;);&#xA;      }&#xA;    } catch (e) {&#xA;      _showError(&#x27;Recording stop error: $e&#x27;);&#xA;    }&#xA;  }&#xA;&#xA;  Future<void> _switchCamera() async {&#xA;    if (_cameras.length &lt;= 1) return;&#xA;&#xA;    if (_isRecording) {&#xA;      await _stopAndSaveVideoRecording();&#xA;      _currentCameraIndex = (_currentCameraIndex &#x2B; 1) % _cameras.length;&#xA;      await _initializeCameraController(_cameras[_currentCameraIndex]);&#xA;      await _startVideoRecording();&#xA;    } else {&#xA;      _currentCameraIndex = (_currentCameraIndex &#x2B; 1) % _cameras.length;&#xA;      await _initializeCameraController(_cameras[_currentCameraIndex]);&#xA;    }&#xA;  }&#xA;&#xA;  Future<void> _toggleRecording() async {&#xA;    if (_cameraController == null) return;&#xA;&#xA;    if (_isRecording) {&#xA;      await _stopAndSaveVideoRecording();&#xA;      await _stopAndSaveAudioRecording();&#xA;    } else {&#xA;      _startVideoRecording();&#xA;      _startAudioRecording();&#xA;      setState(() => _recordedVideos.clear());&#xA;    }&#xA;  }&#xA;}&#xA;</void></void></void></void></void></void></void></void></void></string></cameradescription></mergevideorecording></mergevideorecording>

    &#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;