Recherche avancée

Médias (91)

Autres articles (88)

  • Websites made ​​with MediaSPIP

    2 mai 2011, par

    This page lists some websites based on MediaSPIP.

  • Creating farms of unique websites

    13 avril 2011, par

    MediaSPIP platforms can be installed as a farm, with a single "core" hosted on a dedicated server and used by multiple websites.
    This allows (among other things) : implementation costs to be shared between several different projects / individuals rapid deployment of multiple unique sites creation of groups of like-minded sites, making it possible to browse media in a more controlled and selective environment than the major "open" (...)

  • Organiser par catégorie

    17 mai 2013, par

    Dans MédiaSPIP, une rubrique a 2 noms : catégorie et rubrique.
    Les différents documents stockés dans MédiaSPIP peuvent être rangés dans différentes catégories. On peut créer une catégorie en cliquant sur "publier une catégorie" dans le menu publier en haut à droite ( après authentification ). Une catégorie peut être rangée dans une autre catégorie aussi ce qui fait qu’on peut construire une arborescence de catégories.
    Lors de la publication prochaine d’un document, la nouvelle catégorie créée sera proposée (...)

Sur d’autres sites (6406)

  • FFmpeg Overwiting Playlist

    30 septembre 2024, par Program-Me-Rev

    I'm working on an implementation where I aim to generate a DASH Playlist from Raw Camera2 data in Android Java using FFmpeg

    


    However , the current implementation only produces Three .m4s files regardless of how long the recording lasts . My goal is to create a playlist with 1-second .m4s Segments , but the output only includes the following files , and the video length doesn't exceed 2 seconds :

    


    - playlist.mpd
- init.m4s
- 1.m4s
- 2.m4s


    


    While the temporary files are created as expected , the .m4s files stop after these two segments . Additionally , only the last 2 seconds of the recording are retained , no matter how long the recording runs

    


    The FFmpeg output indicates that FFmpeg is repeatedly overwriting the previously generated playlist , which may explain why the recording doesn't extend beyond 2 seconds

    


    FFmpeg version : 6.0

    


        package rev.ca.rev_media_dash_camera2;&#xA;&#xA;    import android.app.Activity;&#xA;    import android.content.Context;&#xA;    import android.media.Image;&#xA;    import android.util.Log;&#xA;    import android.util.Size;&#xA;&#xA;    import androidx.annotation.NonNull;&#xA;    import androidx.camera.core.CameraSelector;&#xA;    import androidx.camera.core.ImageAnalysis;&#xA;    import androidx.camera.core.ImageProxy;&#xA;    import androidx.camera.core.Preview;&#xA;    import androidx.camera.lifecycle.ProcessCameraProvider;&#xA;    import androidx.camera.view.PreviewView;&#xA;    import androidx.core.content.ContextCompat;&#xA;    import androidx.lifecycle.LifecycleOwner;&#xA;&#xA;    import com.arthenica.ffmpegkit.FFmpegKit;&#xA;    import com.arthenica.ffmpegkit.ReturnCode;&#xA;    import com.google.common.util.concurrent.ListenableFuture;&#xA;&#xA;    import java.io.File;&#xA;    import java.io.FileOutputStream;&#xA;    import java.io.IOException;&#xA;    import java.nio.ByteBuffer;&#xA;    import java.util.concurrent.ExecutionException;&#xA;    import java.util.concurrent.ExecutorService;&#xA;    import java.util.concurrent.Executors;&#xA;&#xA;    public class RevCameraCapture {&#xA;        private static final String REV_TAG = "RevCameraCapture";&#xA;&#xA;        private final Context revContext;&#xA;        private final ExecutorService revExecutorService;&#xA;        private final String revOutDirPath = "/storage/emulated/0/Documents/Owki/rev_web_rtc_live_chat_temp_files/_abc_rev_uploads_temp";&#xA;        private boolean isRevRecording;&#xA;        private File revTempFile;&#xA;        private int revFrameCount = 0; // Counter for frames captured&#xA;&#xA;        public RevCameraCapture(Context revContext) {&#xA;            this.revContext = revContext;&#xA;&#xA;            revInitDir(revOutDirPath);&#xA;            revCheckOrCreatePlaylist();&#xA;&#xA;            revExecutorService = Executors.newSingleThreadExecutor();&#xA;        }&#xA;&#xA;        private void revInitDir(String revDirPath) {&#xA;            // Create a File object for the directory&#xA;            File revNestedDir = new File(revDirPath);&#xA;&#xA;            // Check if the directory exists, if not, create it&#xA;            if (!revNestedDir.exists()) {&#xA;                boolean revResult = revNestedDir.mkdirs();  // mkdirs() creates the whole path&#xA;                if (revResult) {&#xA;                    Log.e(REV_TAG, ">>> Directories created successfully.");&#xA;                } else {&#xA;                    Log.e(REV_TAG, ">>> Failed to create directories.");&#xA;                }&#xA;            } else {&#xA;                Log.e(REV_TAG, ">>> Directories already exist.");&#xA;            }&#xA;        }&#xA;&#xA;        private void revCheckOrCreatePlaylist() {&#xA;            File revPlaylistFile = new File(revOutDirPath, "rev_playlist.mpd");&#xA;            if (!revPlaylistFile.exists()) {&#xA;                // Create an empty playlist if it doesn&#x27;t exist&#xA;                try {&#xA;                    FileOutputStream revFos = new FileOutputStream(revPlaylistFile);&#xA;                    revFos.write("".getBytes());&#xA;                    revFos.close();&#xA;                } catch (IOException e) {&#xA;                    Log.e(REV_TAG, ">>> Error creating initial rev_playlist : ", e);&#xA;                }&#xA;            }&#xA;        }&#xA;&#xA;&#xA;        private void revStartFFmpegProcess() {&#xA;            // Ensure revTempFile exists before processing&#xA;            if (revTempFile == null || !revTempFile.exists()) {&#xA;                Log.e(REV_TAG, ">>> Temporary file does not exist for FFmpeg processing.");&#xA;                return;&#xA;            }&#xA;&#xA;            // FFmpeg command to convert the temp file to DASH format and append to the existing rev_playlist&#xA;            String ffmpegCommand = "-f rawvideo -pixel_format yuv420p -video_size 704x704 " &#x2B; "-i " &#x2B; revTempFile.getAbsolutePath() &#x2B; " -c:v mpeg4 -b:v 1M " &#x2B; "-f dash -seg_duration 1 -use_template 1 -use_timeline 1 " &#x2B; "-init_seg_name &#x27;init.m4s&#x27; -media_seg_name &#x27;$Number$.m4s&#x27; " &#x2B; revOutDirPath &#x2B; "/rev_playlist.mpd -loglevel debug";&#xA;&#xA;&#xA;            FFmpegKit.executeAsync(ffmpegCommand, session -> {&#xA;                ReturnCode returnCode = session.getReturnCode();&#xA;                if (ReturnCode.isSuccess(returnCode)) {&#xA;                    // Optionally handle success, e.g., log or notify that the process completed successfully&#xA;                } else {&#xA;                    Log.e(REV_TAG, ">>> FFmpeg process failed with return code : " &#x2B; returnCode);&#xA;                }&#xA;            });&#xA;        }&#xA;&#xA;&#xA;        public void revStartCamera() {&#xA;            isRevRecording = true;&#xA;&#xA;            ListenableFuture<processcameraprovider> revCameraProviderFuture = ProcessCameraProvider.getInstance(revContext);&#xA;&#xA;            revCameraProviderFuture.addListener(() -> {&#xA;                try {&#xA;                    ProcessCameraProvider revCameraProvider = revCameraProviderFuture.get();&#xA;                    revBindPreview(revCameraProvider);&#xA;                    revBindImageAnalysis(revCameraProvider);&#xA;                } catch (ExecutionException | InterruptedException e) {&#xA;                    Log.e(REV_TAG, ">>> Failed to start camera : ", e);&#xA;                }&#xA;            }, ContextCompat.getMainExecutor(revContext));&#xA;        }&#xA;&#xA;        private void revBindPreview(ProcessCameraProvider revCameraProvider) {&#xA;            CameraSelector revCameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();&#xA;&#xA;            PreviewView previewView = ((Activity) revContext).findViewById(R.id.previewView);&#xA;            Preview preview = new Preview.Builder().build();&#xA;            preview.setSurfaceProvider(previewView.getSurfaceProvider());&#xA;&#xA;            revCameraProvider.unbindAll();&#xA;            revCameraProvider.bindToLifecycle((LifecycleOwner) revContext, revCameraSelector, preview);&#xA;        }&#xA;&#xA;        private void revBindImageAnalysis(@NonNull ProcessCameraProvider revCameraProvider) {&#xA;            ImageAnalysis revImageAnalysis = new ImageAnalysis.Builder().setTargetResolution(new Size(640, 480)) // Lower the resolution to reduce memory consumption&#xA;                    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build();&#xA;&#xA;            revImageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(revContext), this::revAnalyze);&#xA;            CameraSelector revCameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();&#xA;&#xA;            revCameraProvider.bindToLifecycle((LifecycleOwner) revContext, revCameraSelector, revImageAnalysis);&#xA;        }&#xA;&#xA;        @androidx.annotation.OptIn(markerClass = androidx.camera.core.ExperimentalGetImage.class)&#xA;        private void revAnalyze(@NonNull ImageProxy revImageProxy) {&#xA;            try {&#xA;                revProcessImageFrame(revImageProxy);&#xA;            } catch (Exception e) {&#xA;                Log.e(REV_TAG, ">>> Error processing revImage frame", e);&#xA;            } finally {&#xA;                revImageProxy.close(); // Always close the revImageProxy&#xA;            }&#xA;        }&#xA;&#xA;        @androidx.annotation.OptIn(markerClass = androidx.camera.core.ExperimentalGetImage.class)&#xA;        private void revProcessImageFrame(@NonNull ImageProxy revImageProxy) {&#xA;            Image revImage = revImageProxy.getImage();&#xA;            if (revImage != null) {&#xA;                byte[] revImageBytes = revConvertYUV420888ToByteArray(revImage);&#xA;                revWriteFrameToTempFile(revImageBytes); // Write frame to a temporary file&#xA;            }&#xA;            revImageProxy.close(); // Close the ImageProxy to release the revImage buffer&#xA;        }&#xA;&#xA;        private byte[] revConvertYUV420888ToByteArray(Image revImage) {&#xA;            Image.Plane[] planes = revImage.getPlanes();&#xA;            ByteBuffer revBufferY = planes[0].getBuffer();&#xA;            ByteBuffer revBufferU = planes[1].getBuffer();&#xA;            ByteBuffer revBufferV = planes[2].getBuffer();&#xA;&#xA;            int revWidth = revImage.getWidth();&#xA;            int revHeight = revImage.getHeight();&#xA;&#xA;            int revSizeY = revWidth * revHeight;&#xA;            int revSizeUV = (revWidth / 2) * (revHeight / 2); // U and V sizes are half the Y size&#xA;&#xA;            // Total size = Y &#x2B; U &#x2B; V&#xA;            byte[] revData = new byte[revSizeY &#x2B; 2 * revSizeUV];&#xA;&#xA;            // Copy Y plane&#xA;            revBufferY.get(revData, 0, revSizeY);&#xA;&#xA;            // Copy U and V planes, accounting for row stride and pixel stride&#xA;            int revOffset = revSizeY;&#xA;            int revPixelStrideU = planes[1].getPixelStride();&#xA;            int rowStrideU = planes[1].getRowStride();&#xA;            int revPixelStrideV = planes[2].getPixelStride();&#xA;            int rowStrideV = planes[2].getRowStride();&#xA;&#xA;            // Copy U plane&#xA;            for (int row = 0; row &lt; revHeight / 2; row&#x2B;&#x2B;) {&#xA;                for (int col = 0; col &lt; revWidth / 2; col&#x2B;&#x2B;) {&#xA;                    revData[revOffset&#x2B;&#x2B;] = revBufferU.get(row * rowStrideU &#x2B; col * revPixelStrideU);&#xA;                }&#xA;            }&#xA;&#xA;            // Copy V plane&#xA;            for (int row = 0; row &lt; revHeight / 2; row&#x2B;&#x2B;) {&#xA;                for (int col = 0; col &lt; revWidth / 2; col&#x2B;&#x2B;) {&#xA;                    revData[revOffset&#x2B;&#x2B;] = revBufferV.get(row * rowStrideV &#x2B; col * revPixelStrideV);&#xA;                }&#xA;            }&#xA;&#xA;            return revData;&#xA;        }&#xA;&#xA;&#xA;        private void revWriteFrameToTempFile(byte[] revImageBytes) {&#xA;            revExecutorService.execute(() -> {&#xA;                try {&#xA;                    // Create a new temp file for each segment if needed&#xA;                    if (revTempFile == null || revFrameCount == 0) {&#xA;                        revTempFile = File.createTempFile("vid_segment_", ".yuv", new File(revOutDirPath));&#xA;                    }&#xA;&#xA;                    try (FileOutputStream revFos = new FileOutputStream(revTempFile, true)) {&#xA;                        revFos.write(revImageBytes);&#xA;                    }&#xA;&#xA;                    revFrameCount&#x2B;&#x2B;;&#xA;&#xA;                    // Process after 60 frames (2 second for 30 fps)&#xA;                    if (revFrameCount >= 60 &amp;&amp; isRevRecording) {&#xA;                        revStartFFmpegProcess();  // Process the segment with FFmpeg&#xA;                        revFrameCount = 0;  // Reset the frame count&#xA;                        revTempFile = null;  // Reset temp file for the next segment&#xA;                    }&#xA;&#xA;                } catch (IOException e) {&#xA;                    Log.e(REV_TAG, ">>> Error writing frame to temp file : ", e);&#xA;                }&#xA;            });&#xA;        }&#xA;&#xA;        public void revStopCamera() {&#xA;            isRevRecording = false;&#xA;            if (revTempFile != null &amp;&amp; revTempFile.exists()) {&#xA;                revTempFile.delete(); // Clean up the temporary file&#xA;                revTempFile = null; // Reset the temp file reference&#xA;            }&#xA;        }&#xA;    }&#xA;&#xA;&#xA;    package rev.ca.rev_media_dash_camera2;&#xA;&#xA;    import android.os.Bundle;&#xA;&#xA;    import androidx.appcompat.app.AppCompatActivity;&#xA;&#xA;    public class MainActivity extends AppCompatActivity {&#xA;        private RevCameraCapture revCameraCapture;&#xA;&#xA;        @Override&#xA;        protected void onCreate(Bundle savedInstanceState) {&#xA;            super.onCreate(savedInstanceState);&#xA;            setContentView(R.layout.activity_main);&#xA;&#xA;            revCameraCapture = new RevCameraCapture(this);&#xA;        }&#xA;&#xA;        @Override&#xA;        protected void onStart() {&#xA;            super.onStart();&#xA;            try {&#xA;                revCameraCapture.revStartCamera();&#xA;            } catch (Exception e) {&#xA;                e.printStackTrace();&#xA;            }&#xA;        }&#xA;&#xA;        @Override&#xA;        protected void onStop() {&#xA;            super.onStop();&#xA;            revCameraCapture.revStopCamera(); // Ensure camera is stopped when not in use&#xA;        }&#xA;    }&#xA;</processcameraprovider>

    &#xA;

  • High quality screen capture using ffmpeg on wayland [closed]

    27 novembre 2024, par Charlie Benger-Stevenson

    Running hyprland/wayland on arch.

    &#xA;

    I want a reasonable quality (for say youtube) screen capture.

    &#xA;

    ffmpeg -device /dev/dri/card1 -re -f kmsgrab -i - -vf &#x27;hwmap=derive_device=vaapi,hwdownload,format=bgr0&#x27; -s 1920x1080 -c:v mpeg2video -b:v 1M -t 5  ~/Recordings/screencap.avi&#xA;

    &#xA;

    This should set a bitrate of 1M but the output is super blocky with a much lower bitrate than specified by the b:v flag.

    &#xA;

    What am I doing wrong ?

    &#xA;

  • WordPress Analytics plugin WP-Piwik reaches version 1.0.0 (and 50,000 active users)

    29 mai 2015, par André Bräkling — Plugins

    After six years of development, we are proud to announce the 1.0.0 release of our WP-Piwik WordPress plugin !

    Started as a simple plugin to show a selection of statistics within the WordPress dashboard, WP-Piwik has become a full Piwik integration plugin. The plugin automatically adds the Piwik tracking code to your WordPress sites. The plugin displays your analytics reports directly within the WordPress admin panel. WordPress networks (“multisite”), CDN URLs and the Piwik proxy script are also supported.

    According to WordPress.org the plugin is being used by more than 50,000 WordPress sites !

    This article explains how to install WP-Piwik and how to configure it to work with your Piwik instance.

    Install WP-Piwik

    You can get WP-Piwik using WordPress’ plugin management. Login to your WordPress admin dashboard and go to « Plugins » → « Add New ». Enter « WP-Piwik » into the search field at the top right, press enter and next to WP-Piwik choose « Install Now ».

    If you want to use WP-Piwik in your simple WordPress blog you can just click « Activate Plugin » and WP-Piwik will ask you to configure your Piwik connection.

    Running a WordPress network/multisite you can choose to « Network Activate » the plugin after the installation process. In this case, WP-Piwik will be a fully automated feature of your WordPress network automatically tracking your sites in the same Piwik instance in separate Websites.

    Alternatively you can download WP-Piwik manually from the WordPress website and upload all files to your `wp-content/plugins` directory.

    Configure your Piwik connection

    WP-Piwik lets you choose between three connection modes :

    • Self-hosted (HTTP API) : This is the default option for a self-hosted Piwik and should work for most configurations. You just have to know your Piwik URL, which is the URL you enter to access Piwik, and your auth token (see below). WP-Piwik will connect to Piwik using http(s)-requests.
    • Self-hosted (PHP API) : Choose this, if your self-hosted Piwik and WordPress are running on the same machine and you know the full server path to your Piwik instance. Beside the full server path, you also need to know your auth token (see below).
    • Cloud-hosted (Piwik Pro) : If you are using a cloud-hosted Piwik by Piwik Pro, you just need to know your user name and your auth token (see below).

    Setting up WP-Piwik

    To configure WP-Piwik you will need to specify your Authentication token.

    • If the site you want to track in Piwik is already configured in your Piwik, you only need to specify a token_auth for a user with `view` permission.
    • If you want WP-Piwik to create the website in Piwik (or if you use WP-Piwik in network mode which requires to be able to configure your sites), you should specify a token_auth which has Super User access (after the setting up phase is completed you can set the authentication token back to the token of a `view` user).

    To find your token_auth in Piwik, click on your user name in the right right corner of your Piwik dashboard, then click the « API » in the left menu. The API page displays your auth token in a colored box, just behind the “&token_auth=” string. The screenshot below shows the token_auth anonymous, but your real one will be an alpha numerous random string like a1ec31524a8eabc7a546d71d68b28d17.

    That’s it. After you entered your connection data and submitted the form, WP-Piwik will welcome you with some information :

    You can now start to configure WP-Piwik and enable the tracking code. Learn about any setting by clicking on the small question mark sign. If you have any problem configuring or using WP-Piwik feel free to use the WordPress support forum related to WP-Piwik.

    Translating WP-Piwik

    We invite you to join our translation community at Transifex and help to translate WP-Piwik in more languages !

    Happy WordPress Analytics !