Recherche avancée

Médias (0)

Mot : - Tags -/configuration

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

Autres articles (58)

  • Publier sur MédiaSpip

    13 juin 2013

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

  • Librairies et logiciels spécifiques aux médias

    10 décembre 2010, par

    Pour un fonctionnement correct et optimal, plusieurs choses sont à prendre en considération.
    Il est important, après avoir installé apache2, mysql et php5, d’installer d’autres logiciels nécessaires dont les installations sont décrites dans les liens afférants. Un ensemble de librairies multimedias (x264, libtheora, libvpx) utilisées pour l’encodage et le décodage des vidéos et sons afin de supporter le plus grand nombre de fichiers possibles. Cf. : ce tutoriel ; FFMpeg avec le maximum de décodeurs et (...)

  • List of compatible distributions

    26 avril 2011, par

    The table below is the list of Linux distributions compatible with the automated installation script of MediaSPIP. Distribution nameVersion nameVersion number Debian Squeeze 6.x.x Debian Weezy 7.x.x Debian Jessie 8.x.x Ubuntu The Precise Pangolin 12.04 LTS Ubuntu The Trusty Tahr 14.04
    If you want to help us improve this list, you can provide us access to a machine whose distribution is not mentioned above or send the necessary fixes to add (...)

Sur d’autres sites (8370)

  • Is there a way to extract frames from a video file using ffmpeg to memory and make some manipulation on each frame ?

    28 octobre 2022, par Rojer Brief

    The goal is to extract each time a frame from the video file then make histogram from the image and then to move to the next frame. this way all the frames.

    


    The frames extraction and the histogram manipulation is working fine when the frames have saved as images on the hard disk. but now i want to do it all in memory.

    


    to extract the frames i'm using ffmpeg because i think it's fast enough :

    


    ffmpeg -r 1 -i MyVid.mp4 -r 1 "$filename%03d.png


    


    for now i'm using the ffmpeg in command prompt window.

    


    with this command it will save on the hard disk over 65000 images(frames).
but instead saving them on the hard disk i wonder if i can make the histogram manipulation on each frame in memory instead saving all the 65000 frames to the hard disk.

    


    then i want to find specific images using the histogram and save to the hard disk this frames.

    


    the histogram part for now is also using files from the hard disk and not from the memory :

    


    private void btnLoadHistogram_Click(object sender, System.EventArgs e)
        {
            string[] files = Directory.GetFiles(@"d:\screenshots\", "*.jpg");

            for (int i = 0; i < files.Length; i++)
            {
                sbInfo.Text = "Loading image";
                if (pbImage.Image != null)
                    pbImage.Image.Dispose();

                pbImage.Image = Image.FromFile(files[i]);//txtFileName.Text);

                Application.DoEvents();

                sbInfo.Text = "Computing histogram";
                long[] myValues = GetHistogram(new Bitmap(pbImage.Image));

                Histogram.DrawHistogram(myValues);

                sbInfo.Text = "";   
            }   
        }

        public long[] GetHistogram(System.Drawing.Bitmap picture)
        {
            long[] myHistogram = new long[256];

            for (int i=0;i3;
                    myHistogram[Temp]++;
                }

            return myHistogram;
        }


    


    and the code of the class of the constrol HistogramaDesenat :

    


    using System;&#xA;using System.Collections;&#xA;using System.ComponentModel;&#xA;using System.Drawing;&#xA;using System.Data;&#xA;using System.Windows.Forms;&#xA;&#xA;namespace Histograma&#xA;{&#xA;    /// <summary>&#xA;    /// Summary description for HistogramaDesenat.&#xA;    /// </summary>&#xA;    public class HistogramaDesenat : System.Windows.Forms.UserControl&#xA;    {&#xA;        /// <summary> &#xA;        /// Required designer variable.&#xA;        /// </summary>&#xA;        private System.ComponentModel.Container components = null;&#xA;&#xA;        public HistogramaDesenat()&#xA;        {&#xA;            // This call is required by the Windows.Forms Form Designer.&#xA;            InitializeComponent();&#xA;&#xA;            // TODO: Add any initialization after the InitializeComponent call&#xA;&#xA;            this.Paint &#x2B;= new PaintEventHandler(HistogramaDesenat_Paint);&#xA;            this.Resize&#x2B;=new EventHandler(HistogramaDesenat_Resize);&#xA;        }&#xA;&#xA;        /// <summary> &#xA;        /// Clean up any resources being used.&#xA;        /// </summary>&#xA;        protected override void Dispose( bool disposing )&#xA;        {&#xA;            if( disposing )&#xA;            {&#xA;                if(components != null)&#xA;                {&#xA;                    components.Dispose();&#xA;                }&#xA;            }&#xA;            base.Dispose( disposing );&#xA;        }&#xA;&#xA;        #region Component Designer generated code&#xA;        /// <summary> &#xA;        /// Required method for Designer support - do not modify &#xA;        /// the contents of this method with the code editor.&#xA;        /// </summary>&#xA;        private void InitializeComponent()&#xA;        {&#xA;            // &#xA;            // HistogramaDesenat&#xA;            // &#xA;            this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));&#xA;            this.Name = "HistogramaDesenat";&#xA;            this.Size = new System.Drawing.Size(208, 176);&#xA;        }&#xA;        #endregion&#xA;&#xA;        private void HistogramaDesenat_Paint(object sender, PaintEventArgs e)&#xA;        {&#xA;            if (myIsDrawing)&#xA;            {&#xA;&#xA;                Graphics g = e.Graphics;&#xA;                Pen myPen = new Pen(new SolidBrush(myColor),myXUnit);&#xA;                //The width of the pen is given by the XUnit for the control.&#xA;                for (int i=0;i/We draw each line &#xA;                    g.DrawLine(myPen,&#xA;                        new PointF(myOffset &#x2B; (i*myXUnit), this.Height - myOffset), &#xA;                        new PointF(myOffset &#x2B; (i*myXUnit), this.Height - myOffset - myValues[i] * myYUnit));&#xA;&#xA;                    //We plot the coresponding index for the maximum value.&#xA;                    if (myValues[i]==myMaxValue)&#xA;                    {&#xA;                        SizeF mySize = g.MeasureString(i.ToString(),myFont);&#xA;&#xA;                        g.DrawString(i.ToString(),myFont,new SolidBrush(myColor),&#xA;                            new PointF(myOffset &#x2B; (i*myXUnit) - (mySize.Width/2), this.Height - myFont.Height ),&#xA;                            System.Drawing.StringFormat.GenericDefault);&#xA;                    }&#xA;                }&#xA;&#xA;                //We draw the indexes for 0 and for the length of the array beeing plotted&#xA;                g.DrawString("0",myFont, new SolidBrush(myColor),new PointF(myOffset,this.Height - myFont.Height),System.Drawing.StringFormat.GenericDefault);&#xA;                g.DrawString((myValues.Length-1).ToString(),myFont, &#xA;                    new SolidBrush(myColor),&#xA;                    new PointF(myOffset &#x2B; (myValues.Length * myXUnit) - g.MeasureString((myValues.Length-1).ToString(),myFont).Width,&#xA;                    this.Height - myFont.Height),&#xA;                    System.Drawing.StringFormat.GenericDefault);&#xA;&#xA;                //We draw a rectangle surrounding the control.&#xA;                g.DrawRectangle(new System.Drawing.Pen(new SolidBrush(Color.Black),1),0,0,this.Width-1,this.Height-1);&#xA;            }&#xA;&#xA;        }&#xA;&#xA;        long myMaxValue;&#xA;        private long[] myValues;&#xA;        private bool myIsDrawing;&#xA;&#xA;        private float myYUnit; //this gives the vertical unit used to scale our values&#xA;        private float myXUnit; //this gives the horizontal unit used to scale our values&#xA;        private int myOffset = 20; //the offset, in pixels, from the control margins.&#xA;&#xA;        private Color myColor = Color.Black;&#xA;        private Font myFont = new Font("Tahoma",10);&#xA;&#xA;        [Category("Histogram Options")]&#xA;        [Description ("The distance from the margins for the histogram")]&#xA;        public int Offset&#xA;        {&#xA;            set&#xA;            {&#xA;                if (value>0)&#xA;                    myOffset= value;&#xA;            }&#xA;            get&#xA;            {&#xA;                return myOffset;&#xA;            }&#xA;        }&#xA;&#xA;        [Category("Histogram Options")]&#xA;        [Description ("The color used within the control")]&#xA;        public Color DisplayColor&#xA;        {&#xA;            set&#xA;            {&#xA;                myColor = value;&#xA;            }&#xA;            get&#xA;            {&#xA;                return myColor;&#xA;            }&#xA;        }&#xA;&#xA;        /// <summary>&#xA;        /// We draw the histogram on the control&#xA;        /// </summary>&#xA;        /// The values beeing draw&#xA;        public void DrawHistogram(long[] Values)&#xA;        {&#xA;            myValues = new long[Values.Length];&#xA;            Values.CopyTo(myValues,0);&#xA;&#xA;            myIsDrawing = true;&#xA;            myMaxValue = getMaxim(myValues);&#xA;&#xA;            ComputeXYUnitValues();&#xA;&#xA;            this.Refresh();&#xA;        }&#xA;&#xA;        /// <summary>&#xA;        /// We get the highest value from the array&#xA;        /// </summary>&#xA;        /// The array of values in which we look&#xA;        /// <returns>The maximum value</returns>&#xA;        private long getMaxim(long[] Vals)&#xA;        {&#xA;            if (myIsDrawing)&#xA;            {&#xA;                long max = 0;&#xA;                for (int i=0;i max)&#xA;                        max = Vals[i];&#xA;                }&#xA;                return max;&#xA;            }&#xA;            return 1;&#xA;        }&#xA;&#xA;        private void HistogramaDesenat_Resize(object sender, EventArgs e)&#xA;        {&#xA;            if (myIsDrawing)&#xA;            {&#xA;                ComputeXYUnitValues();&#xA;            }&#xA;            this.Refresh();&#xA;        }&#xA;&#xA;        private void ComputeXYUnitValues()&#xA;        {&#xA;            myYUnit = (float) (this.Height - (2 * myOffset)) / myMaxValue;&#xA;            myXUnit = (float) (this.Width - (2 * myOffset)) / (myValues.Length-1);&#xA;        }&#xA;    }&#xA;}&#xA;

    &#xA;

    so in the end this is what i want to do :

    &#xA;

      &#xA;
    • extract the frames from the video file in memory using the ffmpeg.

      &#xA;

    • &#xA;

    • instead using Directory.GetFiles i want to make the histogram manipulation on each frame from the memory that is extracted by the ffmpeg.

      &#xA;

    • &#xA;

    • each extracted frame image to use the histogram to find if there is a lightning(weather lightning) in the image.

      &#xA;

    • &#xA;

    • if there is a lightning save the frame image to the hard disk.

      &#xA;

    • &#xA;

    &#xA;

  • ffmpeg encoding leaves me with blank space at the end where the video pauses and there is nothing ahead

    6 novembre 2022, par Nisarg Desai

    I was trying to slice some of the video being played and clip it in mpv.net using a .lua script which uses ffmpeg to encode the webm output. ffmpeg sometimes leaves some seconds blank and without any video/audio ahead while clipping from source. Is there any solution to this ?

    &#xA;

    The code for the script is given below (was taken from here https://github.com/occivink/mpv-scripts) :

    &#xA;

    local utils = require "mp.utils"&#xA;local msg = require "mp.msg"&#xA;local options = require "mp.options"&#xA;&#xA;local ON_WINDOWS = (package.config:sub(1,1) ~= "/")&#xA;&#xA;local start_timestamp = nil&#xA;local profile_start = ""&#xA;&#xA;-- implementation detail of the osd message&#xA;local timer = nil&#xA;local timer_duration = 2&#xA;&#xA;-- folder creation if it doesnt exist&#xA;function exists(file)&#xA;   local ok, err, code = os.rename(file, file)&#xA;   if not ok then&#xA;      if code == 13 then&#xA;         return true&#xA;      end&#xA;   end&#xA;   return ok, err&#xA;end&#xA;&#xA;--- Check if a directory exists in this path&#xA;function create_dir(path)&#xA;    local dir = "\"" .. path .. "\""&#xA;    if not exists(path .."/") then&#xA;        os.execute("mkdir " .. dir)&#xA;    end&#xA;end&#xA;&#xA;function append_table(lhs, rhs)&#xA;    for i = 1,#rhs do&#xA;        lhs[#lhs&#x2B;1] = rhs[i]&#xA;    end&#xA;    return lhs&#xA;end&#xA;&#xA;function file_exists(name)&#xA;    local f = io.open(name, "r")&#xA;    if f ~= nil then&#xA;        io.close(f)&#xA;        return true&#xA;    else&#xA;        return false&#xA;    end&#xA;end&#xA;&#xA;function get_extension(path)&#xA;    local candidate = string.match(path, "%.([^.]&#x2B;)$")&#xA;    if candidate then&#xA;        for _, ext in ipairs({ "mkv", "webm", "mp4", "avi" }) do&#xA;            if candidate == ext then&#xA;                return candidate&#xA;            end&#xA;        end&#xA;    end&#xA;    return "mkv"&#xA;end&#xA;&#xA;function get_output_string(dir, format, input, extension, title, from, to, profile)&#xA;    local res = utils.readdir(dir)&#xA;    if not res then&#xA;        return nil&#xA;    end&#xA;    local files = {}&#xA;    for _, f in ipairs(res) do&#xA;        files[f] = true&#xA;    end&#xA;    local output = format&#xA;    output = string.gsub(output, "$f", function() return input end)&#xA;    output = string.gsub(output, "$t", function() return title end)&#xA;    output = string.gsub(output, "$s", function() return seconds_to_time_string(from, true) end)&#xA;    output = string.gsub(output, "$e", function() return seconds_to_time_string(to, true) end)&#xA;    output = string.gsub(output, "$d", function() return seconds_to_time_string(to-from, true) end)&#xA;    output = string.gsub(output, "$x", function() return extension end)&#xA;    output = string.gsub(output, "$p", function() return profile end)&#xA;    if ON_WINDOWS then&#xA;        output = string.gsub(output, "[/\\|&lt;>?:\"*]", "_")&#xA;    end&#xA;    if not string.find(output, "$n") then&#xA;        return files[output] and nil or output&#xA;    end&#xA;    local i = 1&#xA;    while true do&#xA;        local potential_name = string.gsub(output, "$n", tostring(i))&#xA;        if not files[potential_name] then&#xA;            return potential_name&#xA;        end&#xA;        i = i &#x2B; 1&#xA;    end&#xA;end&#xA;&#xA;function get_video_filters()&#xA;    local filters = {}&#xA;    for _, vf in ipairs(mp.get_property_native("vf")) do&#xA;        local name = vf["name"]&#xA;        name = string.gsub(name, &#x27;^lavfi%-&#x27;, &#x27;&#x27;)&#xA;        local filter&#xA;        if name == "crop" then&#xA;            local p = vf["params"]&#xA;            filter = string.format("crop=%d:%d:%d:%d", p.w, p.h, p.x, p.y)&#xA;        elseif name == "mirror" then&#xA;            filter = "hflip"&#xA;        elseif name == "flip" then&#xA;            filter = "vflip"&#xA;        elseif name == "rotate" then&#xA;            local rotation = vf["params"]["angle"]&#xA;            -- rotate is NOT the filter we want here&#xA;            if rotation == "90" then&#xA;                filter = "transpose=clock"&#xA;            elseif rotation == "180" then&#xA;                filter = "transpose=clock,transpose=clock"&#xA;            elseif rotation == "270" then&#xA;                filter = "transpose=cclock"&#xA;            end&#xA;        end&#xA;        filters[#filters &#x2B; 1] = filter&#xA;    end&#xA;    return filters&#xA;end&#xA;&#xA;function get_input_info(default_path, only_active)&#xA;    local accepted = {&#xA;        video = true,&#xA;        audio = not mp.get_property_bool("mute"),&#xA;        sub = mp.get_property_bool("sub-visibility")&#xA;    }&#xA;    local ret = {}&#xA;    for _, track in ipairs(mp.get_property_native("track-list")) do&#xA;        local track_path = track["external-filename"] or default_path&#xA;        if not only_active or (track["selected"] and accepted[track["type"]]) then&#xA;            local tracks = ret[track_path]&#xA;            if not tracks then&#xA;                ret[track_path] = { track["ff-index"] }&#xA;            else&#xA;                tracks[#tracks &#x2B; 1] = track["ff-index"]&#xA;            end&#xA;        end&#xA;    end&#xA;    return ret&#xA;end&#xA;&#xA;function seconds_to_time_string(seconds, full)&#xA;    local ret = string.format("%02d:%02d.%03d"&#xA;        , math.floor(seconds / 60) % 60&#xA;        , math.floor(seconds) % 60&#xA;        , seconds * 1000 % 1000&#xA;    )&#xA;    if full or seconds > 3600 then&#xA;        ret = string.format("%d:%s", math.floor(seconds / 3600), ret)&#xA;    end&#xA;    return ret&#xA;end&#xA;&#xA;function start_encoding(from, to, settings)&#xA;    local args = {&#xA;        settings.ffmpeg_command,&#xA;        "-loglevel", "panic", "-hide_banner",&#xA;    }&#xA;    local append_args = function(table) args = append_table(args, table) end&#xA;&#xA;    local path = mp.get_property("path")&#xA;    local is_stream = not file_exists(path)&#xA;    if is_stream then&#xA;        path = mp.get_property("stream-path")&#xA;    end&#xA;&#xA;    local track_args = {}&#xA;    local start = seconds_to_time_string(from, false)&#xA;    local input_index = 0&#xA;    for input_path, tracks in pairs(get_input_info(path, settings.only_active_tracks)) do&#xA;       append_args({&#xA;            "-ss", start,&#xA;            "-i", input_path,&#xA;        })&#xA;        if settings.only_active_tracks then&#xA;            for _, track_index in ipairs(tracks) do&#xA;                track_args = append_table(track_args, { "-map", string.format("%d:%d", input_index, track_index)})&#xA;            end&#xA;        else&#xA;            track_args = append_table(track_args, { "-map", tostring(input_index)})&#xA;        end&#xA;        input_index = input_index &#x2B; 1&#xA;    end&#xA;&#xA;    append_args({"-to", tostring(to-from)})&#xA;    append_args(track_args)&#xA;&#xA;    -- apply some of the video filters currently in the chain&#xA;    local filters = {}&#xA;    if settings.preserve_filters then&#xA;        filters = get_video_filters()&#xA;    end&#xA;    if settings.append_filter ~= "" then&#xA;        filters[#filters &#x2B; 1] = settings.append_filter&#xA;    end&#xA;    if #filters > 0 then&#xA;        append_args({ "-filter:v", table.concat(filters, ",") })&#xA;    end&#xA;&#xA;    -- split the user-passed settings on whitespace&#xA;    for token in string.gmatch(settings.codec, "[^%s]&#x2B;") do&#xA;        args[#args &#x2B; 1] = token&#xA;    end&#xA;&#xA;    -- path of the output&#xA;    local output_directory = mp.get_property("options/screenshot-directory")&#xA;    -- local checkbool = exists(output_directory.."/")&#xA;    -- mp.osd_message("" .. type(checkbool), timer_duration)&#xA;    -- if not checkbool then    &#xA;    --     os.execute("mkdir" .. output_directory)&#xA;    -- end&#xA;    if output_directory == "" then&#xA;        if is_stream then&#xA;            output_directory = "."&#xA;        else&#xA;            output_directory, _ = utils.split_path(path)&#xA;        end&#xA;    else&#xA;        output_directory = string.gsub(output_directory, "^~", os.getenv("HOME") or "~")&#xA;    end&#xA;    local input_name = mp.get_property("filename/no-ext") or "encode"&#xA;    local title = mp.get_property("media-title")&#xA;    local extension = get_extension(path)&#xA;    local output_name = get_output_string(output_directory, settings.output_format, input_name, extension, title, from, to, settings.profile)&#xA;    if not output_name then&#xA;        mp.osd_message("Invalid path " .. output_directory)&#xA;        return&#xA;    end&#xA;    args[#args &#x2B; 1] = utils.join_path(output_directory, output_name)&#xA;&#xA;    if settings.print then&#xA;        local o = ""&#xA;        -- fuck this is ugly&#xA;        for i = 1, #args do&#xA;            local fmt = ""&#xA;            if i == 1 then&#xA;                fmt = "%s%s"&#xA;            elseif i >= 2 and i &lt;= 4 then&#xA;                fmt = "%s"&#xA;            elseif args[i-1] == "-i" or i == #args or args[i-1] == "-filter:v" then&#xA;                fmt = "%s &#x27;%s&#x27;"&#xA;            else&#xA;                fmt = "%s %s"&#xA;            end&#xA;            o = string.format(fmt, o, args[i])&#xA;        end&#xA;        print(o)&#xA;    end&#xA;    if settings.detached then&#xA;        utils.subprocess_detached({ args = args })&#xA;    else&#xA;        local res = utils.subprocess({ args = args, max_size = 0, cancellable = false })&#xA;        if res.status == 0 then&#xA;            mp.osd_message("Finished encoding succesfully")&#xA;        else&#xA;            mp.osd_message("Failed to encode, check the log")&#xA;        end&#xA;    end&#xA;end&#xA;&#xA;function clear_timestamp()&#xA;    timer:kill()&#xA;    start_timestamp = nil&#xA;    profile_start = ""&#xA;    mp.remove_key_binding("encode-ESC")&#xA;    mp.remove_key_binding("encode-ENTER")&#xA;    mp.osd_message("", 0)&#xA;end&#xA;&#xA;function set_timestamp(profile)&#xA;    if not mp.get_property("path") then&#xA;        mp.osd_message("No file currently playing")&#xA;        return&#xA;    end&#xA;    if not mp.get_property_bool("seekable") then&#xA;        mp.osd_message("Cannot encode non-seekable media")&#xA;        return&#xA;    end&#xA;    create_dir(mp.get_property("options/screenshot-directory"))&#xA;    if not start_timestamp or profile ~= profile_start then&#xA;        profile_start = profile&#xA;        start_timestamp = mp.get_property_number("time-pos")&#xA;        local msg = function()&#xA;            mp.osd_message(&#xA;                string.format("encode [%s]: waiting for end timestamp", profile or "default"),&#xA;                timer_duration&#xA;            )&#xA;        end&#xA;        msg()&#xA;        timer = mp.add_periodic_timer(timer_duration, msg)&#xA;        mp.add_forced_key_binding("ESC", "encode-ESC", clear_timestamp)&#xA;        mp.add_forced_key_binding("ENTER", "encode-ENTER", function() set_timestamp(profile) end)&#xA;    else&#xA;        local from = start_timestamp&#xA;        local to = mp.get_property_number("time-pos")&#xA;        if to &lt;= from then&#xA;            mp.osd_message("Second timestamp cannot be before the first", timer_duration)&#xA;            timer:kill()&#xA;            timer:resume()&#xA;            return&#xA;        end&#xA;        clear_timestamp()&#xA;        mp.osd_message(string.format("Encoding from %s to %s"&#xA;            , seconds_to_time_string(from, false)&#xA;            , seconds_to_time_string(to, false)&#xA;        ), timer_duration)&#xA;        -- include the current frame into the extract&#xA;        local fps = mp.get_property_number("container-fps") or 30&#xA;        to = to &#x2B; 1 / fps / 2&#xA;        local settings = {&#xA;            detached = false,&#xA;            container = "",&#xA;            only_active_tracks = false,&#xA;            preserve_filters = true,&#xA;            append_filter = "",&#xA;            codec = "-c:v libvpx-vp9 -lossless 1 -b:v 1000k -deadline good",&#xA;            output_format = "$f_$n.webm",&#xA;            output_directory = "",&#xA;            ffmpeg_command = "ffmpeg",&#xA;            print = true,&#xA;        }&#xA;        if profile then&#xA;            options.read_options(settings, profile)&#xA;            if settings.container ~= "" then&#xA;                msg.warn("The &#x27;container&#x27; setting is deprecated, use &#x27;output_format&#x27; now")&#xA;                settings.output_format = settings.output_format .. "." .. settings.container&#xA;            end&#xA;            settings.profile = profile&#xA;        else&#xA;            settings.profile = "default"&#xA;        end        &#xA;        start_encoding(from, to, settings)&#xA;    end&#xA;end&#xA;&#xA;mp.add_key_binding(nil, "set-timestamp", set_timestamp)&#xA;

    &#xA;

  • Localization : Add Hindi translation (#2453)

    11 novembre 2022, par saurabhsharma2u
     Localization : Add Hindi translation (#2453)
    

    * Localisation : Update Hindi (India) translation

    * Hindi Translation for Step Method

    * HIndi-India Local messages for additional method

    * file rename as per ISO 639-1 format

    * removed duplicate message, causing the test fail

    * removed duplicate "cifES" error message