Recherche avancée

Médias (91)

Autres articles (103)

  • 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 (...)

  • 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" (...)

Sur d’autres sites (9700)

  • I'm trying to hide information in a H264 video. When I stitch the video up, split it into frames again and try to read it, the information is lost

    18 mai 2024, par Wer Wer

    I'm trying to create a video steganography python script. The algorithm for hiding will be...

    


      

    1. convert any video codec into h264 lossless
    2. 


    3. save the audio of the video and split the h264 video into frames
    4. 


    5. hide my txt secret into frame0 using LSB replacement method
    6. 


    7. stitch the video back up and put in the audio
    8. 


    


    ...and when I want to recover the text, I'll

    


      

    1. save the audio of the video and split the encoded h264 video into frames
    2. 


    3. retrieve my hidden text from frame0 and print the text
    4. 


    


    So, this is what I can do :

    


      

    1. split the video
    2. 


    3. hide the text in frame0
    4. 


    5. retrieve the text from frame0
    6. 


    7. stitch the video
    8. 


    


    But after stitching the video, when I tried to retrieve the text by splitting that encrypted video, it appears that the text has been lost. This is because i got the error

    


    UnicodeEncodeError: &#x27;charmap&#x27; codec can&#x27;t encode character &#x27;\x82&#x27; in position 21: character maps to <undefined>&#xA;</undefined>

    &#xA;

    I'm not sure if my LSB replacement algorithm was lost, which results in my not being able to retrieve my frame 0 information, or if the H264 conversion command I used was a converted my video into H264 lossy version instead of lossless (which I don't believe so because I specified -qp 0)&#xA;This was the command I used to convert my video

    &#xA;

    ffmpeg -i video.mp4 -t 12 -c:v libx264 -preset veryslow -qp 0 output.mp4&#xA;

    &#xA;

    These are my codes

    &#xA;

    import json&#xA;import os&#xA;import magic&#xA;import ffmpeg&#xA;import cv2&#xA;import numpy as np&#xA;&#xA;import subprocess&#xA;&#xA;# Path to the file you want to check&#xA;here = os.path.dirname(os.path.abspath(__file__))&#xA;file_path = os.path.join(here, "output.mp4")&#xA;raw_video = cv2.VideoCapture(file_path)&#xA;audio_output_path = os.path.join(here, "audio.aac")&#xA;final_video_file = os.path.join(here, "output.mp4")&#xA;&#xA;# create a folder to save the frames.&#xA;frames_directory = os.path.join(here, "data1")&#xA;try:&#xA;    if not os.path.exists(frames_directory):&#xA;        os.makedirs(frames_directory)&#xA;except OSError:&#xA;    print("Error: Creating directory of data")&#xA;&#xA;file_path_txt = os.path.join(here, "hiddentext.txt")&#xA;# Read the content of the file in binary mode&#xA;with open(file_path_txt, "r") as f:&#xA;    file_content = f.read()&#xA;# txt_binary_representation = "".join(format(byte, "08b") for byte in file_content)&#xA;# print(file_content)&#xA;&#xA;"""&#xA;use this cmd to convert any video to h264 lossless. original vid in 10 bit depth format&#xA;ffmpeg -i video.mp4 -c:v libx264 -preset veryslow -qp 0 output.mp4&#xA;&#xA;use this cmd to convert any video to h264 lossless. original vid in 8 bit depth format&#xA;ffmpeg -i video.mp4 -c:v libx264 -preset veryslow -crf 0 output.mp4&#xA;&#xA;i used this command to only get first 12 sec of video because the h264 vid is too large &#xA;ffmpeg -i video.mp4 -t 12 -c:v libx264 -preset veryslow -qp 0 output.mp4&#xA;&#xA;check for multiple values to ensure its h264 lossless:&#xA;1. CRF = 0&#xA;2. qp = 0&#xA;3. High 4:4:4 Predictive&#xA;"""&#xA;&#xA;&#xA;# region --codec checking. ensure video is h264 lossless--&#xA;def check_h264_lossless(file_path):&#xA;    try:&#xA;        # Use ffprobe to get detailed codec information, including tags&#xA;        result = subprocess.run(&#xA;            [&#xA;                "ffprobe",&#xA;                "-v",&#xA;                "error",&#xA;                "-show_entries",&#xA;                "stream=codec_name,codec_long_name,profile,level,bit_rate,avg_frame_rate,nb_frames,tags",&#xA;                "-of",&#xA;                "json",&#xA;                file_path,&#xA;            ],&#xA;            stdout=subprocess.PIPE,&#xA;            stderr=subprocess.PIPE,&#xA;            text=True,&#xA;        )&#xA;        # Check if the file is lossless&#xA;        metadata = check_h264_lossless(file_path)&#xA;        print(json.dumps(metadata, indent=4))&#xA;&#xA;        # Check if the CRF value is available in the tags&#xA;        for stream in metadata.get("streams", []):&#xA;            if stream.get("codec_name") == "h264":&#xA;                tags = stream.get("tags", {})&#xA;                crf_value = tags.get("crf")&#xA;                encoder = tags.get("encoder")&#xA;                print(f"CRF value: {crf_value}")&#xA;                print(f"Encoder: {encoder}")&#xA;        return json.loads(result.stdout)&#xA;    except Exception as e:&#xA;        return f"An error occurred: {e}"&#xA;&#xA;&#xA;# endregion&#xA;&#xA;&#xA;# region --splitting video into frames--&#xA;def extract_audio(input_video_path, audio_output_path):&#xA;    if os.path.exists(audio_output_path):&#xA;        print(f"Audio file {audio_output_path} already exists. Skipping extraction.")&#xA;        return&#xA;    command = [&#xA;        "ffmpeg",&#xA;        "-i",&#xA;        input_video_path,&#xA;        "-q:a",&#xA;        "0",&#xA;        "-map",&#xA;        "a",&#xA;        audio_output_path,&#xA;    ]&#xA;    try:&#xA;        subprocess.run(command, check=True)&#xA;        print(f"Audio successfully extracted to {audio_output_path}")&#xA;    except subprocess.CalledProcessError as e:&#xA;        print(f"An error occurred: {e}")&#xA;&#xA;&#xA;def split_into_frames():&#xA;    extract_audio(file_path, audio_output_path)&#xA;    currentframe = 0&#xA;    print("Splitting...")&#xA;    while True:&#xA;        ret, frame = raw_video.read()&#xA;        if ret:&#xA;            name = os.path.join(here, "data1", f"frame{currentframe}.png")&#xA;            # print("Creating..." &#x2B; name)&#xA;            cv2.imwrite(name, frame)&#xA;            currentframe &#x2B;= 1&#xA;        else:&#xA;            print("Complete")&#xA;            break&#xA;&#xA;&#xA;# endregion&#xA;&#xA;&#xA;# region --merge all back into h264 lossless--&#xA;# output_video_file = "output1111.mp4"&#xA;&#xA;&#xA;def stitch_frames_to_video(frames_dir, output_video_path, framerate=60):&#xA;    command = [&#xA;        "ffmpeg",&#xA;        "-y",&#xA;        "-framerate",&#xA;        str(framerate),&#xA;        "-i",&#xA;        os.path.join(frames_dir, "frame%d.png"),&#xA;        "-c:v",&#xA;        "libx264",&#xA;        "-preset",&#xA;        "veryslow",&#xA;        "-qp",&#xA;        "0",&#xA;        output_video_path,&#xA;    ]&#xA;&#xA;    try:&#xA;        subprocess.run(command, check=True)&#xA;        print(f"Video successfully created at {output_video_path}")&#xA;    except subprocess.CalledProcessError as e:&#xA;        print(f"An error occurred: {e}")&#xA;&#xA;&#xA;def add_audio_to_video(video_path, audio_path, final_output_path):&#xA;    command = [&#xA;        "ffmpeg",&#xA;        "-i",&#xA;        video_path,&#xA;        "-i",&#xA;        audio_path,&#xA;        "-c:v",&#xA;        "copy",&#xA;        "-c:a",&#xA;        "aac",&#xA;        "-strict",&#xA;        "experimental",&#xA;        final_output_path,&#xA;    ]&#xA;    try:&#xA;        subprocess.run(command, check=True)&#xA;        print(f"Final video with audio created at {final_output_path}")&#xA;    except subprocess.CalledProcessError as e:&#xA;        print(f"An error occurred: {e}")&#xA;&#xA;&#xA;# endregion&#xA;&#xA;&#xA;def to_bin(data):&#xA;    if isinstance(data, str):&#xA;        return "".join([format(ord(i), "08b") for i in data])&#xA;    elif isinstance(data, bytes) or isinstance(data, np.ndarray):&#xA;        return [format(i, "08b") for i in data]&#xA;    elif isinstance(data, int) or isinstance(data, np.uint8):&#xA;        return format(data, "08b")&#xA;    else:&#xA;        raise TypeError("Type not supported")&#xA;&#xA;&#xA;def encode(image_name, secret_data):&#xA;    image = cv2.imread(image_name)&#xA;    n_bytes = image.shape[0] * image.shape[1] * 3 // 8&#xA;    print("[*] Maximum bytes to encode:", n_bytes)&#xA;    secret_data &#x2B;= "====="&#xA;    if len(secret_data) > n_bytes:&#xA;        raise ValueError("[!] Insufficient bytes, need bigger image or less data")&#xA;    print("[*] Encoding Data")&#xA;&#xA;    data_index = 0&#xA;    binary_secret_data = to_bin(secret_data)&#xA;    data_len = len(binary_secret_data)&#xA;    for row in image:&#xA;        for pixel in row:&#xA;            r, g, b = to_bin(pixel)&#xA;            if data_index &lt; data_len:&#xA;                pixel[0] = int(r[:-1] &#x2B; binary_secret_data[data_index], 2)&#xA;                data_index &#x2B;= 1&#xA;            if data_index &lt; data_len:&#xA;                pixel[1] = int(g[:-1] &#x2B; binary_secret_data[data_index], 2)&#xA;                data_index &#x2B;= 1&#xA;            if data_index &lt; data_len:&#xA;                pixel[2] = int(b[:-1] &#x2B; binary_secret_data[data_index], 2)&#xA;                data_index &#x2B;= 1&#xA;            if data_index >= data_len:&#xA;                break&#xA;    return image&#xA;&#xA;&#xA;def decode(image_name):&#xA;    print("[&#x2B;] Decoding")&#xA;    image = cv2.imread(image_name)&#xA;    binary_data = ""&#xA;    for row in image:&#xA;        for pixel in row:&#xA;            r, g, b = to_bin(pixel)&#xA;            binary_data &#x2B;= r[-1]&#xA;            binary_data &#x2B;= g[-1]&#xA;            binary_data &#x2B;= b[-1]&#xA;    all_bytes = [binary_data[i : i &#x2B; 8] for i in range(0, len(binary_data), 8)]&#xA;    decoded_data = ""&#xA;    for byte in all_bytes:&#xA;        decoded_data &#x2B;= chr(int(byte, 2))&#xA;        if decoded_data[-5:] == "=====":&#xA;            break&#xA;    return decoded_data[:-5]&#xA;&#xA;&#xA;frame0_path = os.path.join(here, "data1", "frame0.png")&#xA;encoded_image_path = os.path.join(here, "data1", "frame0.png")&#xA;&#xA;&#xA;def encoding_function():&#xA;    split_into_frames()&#xA;&#xA;    encoded_image = encode(frame0_path, file_content)&#xA;    cv2.imwrite(encoded_image_path, encoded_image)&#xA;&#xA;    stitch_frames_to_video(frames_directory, file_path)&#xA;    add_audio_to_video(file_path, audio_output_path, final_video_file)&#xA;&#xA;&#xA;def decoding_function():&#xA;    split_into_frames()&#xA;    decoded_message = decode(encoded_image_path)&#xA;    print(f"[&#x2B;] Decoded message: {decoded_message}")&#xA;&#xA;&#xA;# encoding_function()&#xA;decoding_function()&#xA;&#xA;

    &#xA;

    So I tried to put my decoding function into my encoding function like this

    &#xA;

    def encoding_function():&#xA;    split_into_frames()&#xA;&#xA;    encoded_image = encode(frame0_path, file_content)&#xA;    cv2.imwrite(encoded_image_path, encoded_image)&#xA;&#xA;#immediately get frame0 and decode without stitching to check if the data is there&#xA;    decoded_message = decode(encoded_image_path)&#xA;    print(f"[&#x2B;] Decoded message: {decoded_message}")&#xA;&#xA;    stitch_frames_to_video(frames_directory, file_path)&#xA;    add_audio_to_video(file_path, audio_output_path, final_video_file)&#xA;&#xA;

    &#xA;

    This returns my secret text from frame0. But splitting it after stitching does not return my hidden text. The hidden text was lost

    &#xA;

    def decoding_function():&#xA;    split_into_frames()&#xA;#this function is after the encoding_function(). the secret text is lost, resulting in charmap codec #can&#x27;t encode error&#xA;    decoded_message = decode(encoded_image_path)&#xA;    print(f"[&#x2B;] Decoded message: {decoded_message}")&#xA;

    &#xA;

    EDIT :&#xA;So i ran the encoding function first, copied frame0.png out and placed it some where. Then I ran the decoding function, and got another frame0.png.

    &#xA;

    I ran both frame0.png into this python function

    &#xA;

    frame0_data1_path = os.path.join(here, "data1", "frame0.png")&#xA;frame0_data2_path = os.path.join(here, "data2", "frame0.png")&#xA;frame0_data1 = cv2.imread(frame0_data1_path)&#xA;frame0_data2 = cv2.imread(frame0_data2_path)&#xA;&#xA;if frame0_data1 is None:&#xA;    print(f"Error: Could not load image from {frame0_data1_path}")&#xA;elif frame0_data2 is None:&#xA;    print(f"Error: Could not load image from {frame0_data2_path}")&#xA;else:&#xA;&#xA;    if np.array_equal(frame0_data1, frame0_data2):&#xA;        print("The frames are identical.")&#xA;    else:&#xA;        print("The frames are different.")&#xA;

    &#xA;

    ...and apparently both are different. This means my frame0 binary got changed when I stitch back into the video after encoding. Is there a way to make it not change ? Or will h264 or any video codec change a little bit when you stitch the frames back up ?

    &#xA;

  • Anomalie #4751 : Refonte du jeu d’icônes : retours et commentaires

    29 avril 2021

    C’est un immense et chouette boulot que tu as fait avec toutes ces icones personnalisées !
    Et c’est très bien.

    J’espère n’énerver personne pour la suite :p
    J’ai principalement 2 remarques :

    - la première et principale concerne l’icone de rubrique, qui pour moi ne se détache pas assez du fond (ça dépend du thème aussi et où elle est utilisée). Tu as proposé un contour sympa sur le plugin archiviste. Ce contour, plus un peu de couleur serait probablement intéressant.

    - la seconde concerne l’épaisseur des traits, qui n’est pas toujours identique (plus fin généralement) sur certaines icones. C’est pas dramatique, mais par cohérence si c’était la même taille ça serait cool. Je pense à notamment à
    - "suivi des révisions" ,
    ou "plan du site" (celui du bandeau du moins)
    - ou "vider le cache" (qui lui est plus gros)

    une 3è : chez moi l’icone "agenda interne" a un reflet contrairement aux autres (à moins que ce ne soit du au plugin agenda)
    - une 4è : l’icone "gestion des plugins" est un peu comme la rubrique, jaune sans contour, dans certaines situations elle se détache mal

    Le reste des remarques sont des détails et mes préférences, sans drame apparent, à voir selon les humeurs et d’autres avis :

    - certaines icones sont en fond plein (mots par exemple), ça sort un peu de l’apparence filaire des autres
    - une petite touche de couleur sur certaines icones était sympa (article, ou mot, a perdu sa touche de couleur par exemple)
    - le A (français) des icones de langues a le trou du A central à peine visible en petit. Il semble très légèrement trop épais quoi
    - « fonctions avancée" : 1 seul outil avec un engrenage ?
    - "identité du site" : je suis pas fan du terminal (je n’avais absolument pas compris l’analogie), mais s’il est conservé, mettre un peu plus de contraste entre les gris ?
    - je n’ai pas vu comment était la boite du compagnon récemment, mais son logo, je ne suis pas sûr de l’intérêt d’avoir son contour plus épais que les autres
    - SVP : je ne comprends toujours pas l’analogie (tu as repris la même qu’avant donc… bon…)
    - Plugin "Dev" : chez moi il a une icone différente des autres plugins du core ?
    - le "auteur" (le vert surtout, et jaune aussi) sont pas facile à voir. Peut être qu’augmenter la taille du buste par rapport à la tête aiderait ?


    Et sinon, la vue des logos des plugins du core est trop chouette ! C’est magnifique cet ensemble !

  • Android - How can I pass camera stream to ffmpeg, using Camera2 library ?

    29 mars 2021, par Juan José Cetraro

    I am trying to create an app that shows the camera of the device on the screen, and also streams the camera by srt. To do this, I am using Camera2 library, and ffmpeg (in partucular I am using https://github.com/tanersener/mobile-ffmpeg, that is a ffmpeg wrapper for Android).

    &#xA;

    My plan is to get the camera stream using Camera2 (using the method onImageAvailable on ImageReader.OnImageAvailableListener class), and send this stream to udp ://localhost:1234. Then, I can use ffmpeg to get that stream by udp, and send it by srt.

    &#xA;

    I've already solved the part of sending the stream by srt using ffmpeg, and it works fine. In fact, if I set "android_camera" as the input of my ffmpeg command, my app works ok. The problem with this approach, is that if I do that, I block the access to the camera, so I can't show the camera on the screen with another library.

    &#xA;

    I also found a code that uses Camera2 to stream the camera by udp, and it works, but the problem with this code is that converts each frame to bitmap before sending it by udp, and it makes that it is not performant.

    &#xA;

    So, I need to know which is the best way to pass the data by udp to ffmpeg, so ffmpeg could process it and send it by srt ?

    &#xA;

    Camera2 let me to configure which format I want to receive the frames on my listener :

    &#xA;

    ImageReader.newInstance(1280, 720, ImageFormat.JPEG, /*maxImages*/2);&#xA;

    &#xA;

    In this example I am setting JPEG as ImageFormat, but here I let you all the available formats I could use :

    &#xA;

    UNKNOWN, RGB_565, YV12, Y8, Y16, NV16, NV21, YUY2, JPEG, DEPTH_JPEG, YUV_420_888, YUV_422_888, YUV_444_888, FLEX_RGB_888, FLEX_RGBA_8888, RAW_SENSOR, RAW_PRIVATE, RAW10, RAW12, DEPTH16, DEPTH_POINT_CLOUD, RAW_DEPTH, PRIVATE, HEIC

    &#xA;

    This is the method where I am going to receive each frame, and what I need to know is what kind of transformation I have to do before sending the frame by udp to ffmpeg ? :

    &#xA;

    @Override&#xA;public void onImageAvailable(ImageReader reader) {&#xA;&#xA;}&#xA;

    &#xA;

    Thanks in advance for reading the question :)

    &#xA;