Recherche avancée

Médias (0)

Mot : - Tags -/clipboard

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

Autres articles (43)

Sur d’autres sites (8531)

  • Revision 29944 : On peut comptabiliser les pages du privé

    17 juillet 2009, par kent1@… — Log

    On peut comptabiliser les pages du privé

  • Play video using mse (media source extension) in google chrome

    23 août 2019, par liyuqihxc

    I’m working on a project that convert rtsp stream (ffmpeg) and play it on the web page (signalr + mse).

    So far it works pretty much as I expected on the latest version of edge and firefox, but not chrome.

    here’s the code

    public class WebmMediaStreamContext
    {
       private Process _ffProcess;
       private readonly string _cmd;
       private byte[] _initSegment;
       private Task _readMediaStreamTask;
       private CancellationTokenSource _cancellationTokenSource;

       private const string _CmdTemplate = "-i {0} -c:v libvpx -tile-columns 4 -frame-parallel 1 -keyint_min 90 -g 90 -f webm -dash 1 pipe:";

       public static readonly byte[] ClusterStart = { 0x1F, 0x43, 0xB6, 0x75, 0x01, 0x00, 0x00, 0x00 };

       public event EventHandler<clusterreadyeventargs> ClusterReadyEvent;

       public WebmMediaStreamContext(string rtspFeed)
       {
           _cmd = string.Format(_CmdTemplate, rtspFeed);
       }

       public async Task StartConverting()
       {
           if (_ffProcess != null)
               throw new InvalidOperationException();

           _ffProcess = new Process();
           _ffProcess.StartInfo = new ProcessStartInfo
           {
               FileName = "ffmpeg/ffmpeg.exe",
               Arguments = _cmd,
               UseShellExecute = false,
               CreateNoWindow = true,
               RedirectStandardOutput = true
           };
           _ffProcess.Start();

           _initSegment = await ParseInitSegmentAndStartReadMediaStream();
       }

       public byte[] GetInitSegment()
       {
           return _initSegment;
       }

       // Find the first cluster, and everything before it is the InitSegment
       private async Task ParseInitSegmentAndStartReadMediaStream()
       {
           Memory<byte> buffer = new byte[10 * 1024];
           int length = 0;
           while (length != buffer.Length)
           {
               length += await _ffProcess.StandardOutput.BaseStream.ReadAsync(buffer.Slice(length));
               int cluster = buffer.Span.IndexOf(ClusterStart);
               if (cluster >= 0)
               {
                   _cancellationTokenSource = new CancellationTokenSource();
                   _readMediaStreamTask = new Task(() => ReadMediaStreamProc(buffer.Slice(cluster, length - cluster).ToArray(), _cancellationTokenSource.Token), _cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
                   _readMediaStreamTask.Start();
                   return buffer.Slice(0, cluster).ToArray();
               }
           }

           throw new InvalidOperationException();
       }

       private void ReadMoreBytes(Span<byte> buffer)
       {
           int size = buffer.Length;
           while (size > 0)
           {
               int len = _ffProcess.StandardOutput.BaseStream.Read(buffer.Slice(buffer.Length - size));
               size -= len;
           }
       }

       // Parse every single cluster and fire ClusterReadyEvent
       private void ReadMediaStreamProc(byte[] bytesRead, CancellationToken cancel)
       {
           Span<byte> buffer = new byte[5 * 1024 * 1024];
           bytesRead.CopyTo(buffer);
           int bufferEmptyIndex = bytesRead.Length;

           do
           {
               if (bufferEmptyIndex &lt; ClusterStart.Length + 4)
               {
                   ReadMoreBytes(buffer.Slice(bufferEmptyIndex, 1024));
                   bufferEmptyIndex += 1024;
               }

               int clusterDataSize = BitConverter.ToInt32(
                   buffer.Slice(ClusterStart.Length, 4)
                   .ToArray()
                   .Reverse()
                   .ToArray()
               );
               int clusterSize = ClusterStart.Length + 4 + clusterDataSize;
               if (clusterSize > buffer.Length)
               {
                   byte[] newBuffer = new byte[clusterSize];
                   buffer.Slice(0, bufferEmptyIndex).CopyTo(newBuffer);
                   buffer = newBuffer;
               }

               if (bufferEmptyIndex &lt; clusterSize)
               {
                   ReadMoreBytes(buffer.Slice(bufferEmptyIndex, clusterSize - bufferEmptyIndex));
                   bufferEmptyIndex = clusterSize;
               }

               ClusterReadyEvent?.Invoke(this, new ClusterReadyEventArgs(buffer.Slice(0, bufferEmptyIndex).ToArray()));

               bufferEmptyIndex = 0;
           } while (!cancel.IsCancellationRequested);
       }
    }
    </byte></byte></byte></clusterreadyeventargs>

    I use ffmpeg to convert the rtsp stream to vp8 WEBM byte stream and parse it to "Init Segment" (ebml head、info、tracks...) and "Media Segment" (cluster), then send it to browser via signalR

    $(function () {

       var mediaSource = new MediaSource();
       var mimeCodec = 'video/webm; codecs="vp8"';

       var video = document.getElementById('video');

       mediaSource.addEventListener('sourceopen', callback, false);
       function callback(e) {
           var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
           var queue = [];

           sourceBuffer.addEventListener('updateend', function () {
               if (queue.length === 0) {
                   return;
               }

               var base64 = queue[0];
               if (base64.length === 0) {
                   mediaSource.endOfStream();
                   queue.shift();
                   return;
               } else {
                   var buffer = new Uint8Array(atob(base64).split("").map(function (c) {
                       return c.charCodeAt(0);
                   }));
                   sourceBuffer.appendBuffer(buffer);
                   queue.shift();
               }
           }, false);

           var connection = new signalR.HubConnectionBuilder()
               .withUrl("/signalr-video")
               .configureLogging(signalR.LogLevel.Information)
               .build();
           connection.start().then(function () {
               connection.stream("InitVideoReceive")
                   .subscribe({
                       next: function(item) {
                           if (queue.length === 0 &amp;&amp; !!!sourceBuffer.updating) {
                               var buffer = new Uint8Array(atob(item).split("").map(function (c) {
                                   return c.charCodeAt(0);
                               }));
                               sourceBuffer.appendBuffer(buffer);
                               console.log(blockindex++ + " : " + buffer.byteLength);
                           } else {
                               queue.push(item);
                           }
                       },
                       complete: function () {
                           queue.push('');
                       },
                       error: function (err) {
                           console.error(err);
                       }
                   });
           });
       }
       video.src = window.URL.createObjectURL(mediaSource);
    })

    chrome just play the video for 3 5 seconds and then stop for buffering, even though there are plenty of cluster transfered and inserted into SourceBuffer.

    here’s the information in chrome ://media-internals/

    Player Properties :

    render_id: 217
    player_id: 1
    origin_url: http://localhost:52531/
    frame_url: http://localhost:52531/
    frame_title: Home Page
    url: blob:http://localhost:52531/dcb25d89-9830-40a5-ba88-33c13b5c03eb
    info: Selected FFmpegVideoDecoder for video decoding, config: codec: vp8 format: 1 profile: vp8 coded size: [1280,720] visible rect: [0,0,1280,720] natural size: [1280,720] has extra data? false encryption scheme: Unencrypted rotation: 0°
    pipeline_state: kSuspended
    found_video_stream: true
    video_codec_name: vp8
    video_dds: false
    video_decoder: FFmpegVideoDecoder
    duration: unknown
    height: 720
    width: 1280
    video_buffering_state: BUFFERING_HAVE_NOTHING
    for_suspended_start: false
    pipeline_buffering_state: BUFFERING_HAVE_NOTHING
    event: PAUSE

    Log

    Timestamp       Property            Value
    00:00:00 00     origin_url          http://localhost:52531/
    00:00:00 00     frame_url           http://localhost:52531/
    00:00:00 00     frame_title         Home Page
    00:00:00 00     url                 blob:http://localhost:52531/dcb25d89-9830-40a5-ba88-33c13b5c03eb
    00:00:00 00     info                ChunkDemuxer: buffering by DTS
    00:00:00 35     pipeline_state      kStarting
    00:00:15 213    found_video_stream  true
    00:00:15 213    video_codec_name    vp8
    00:00:15 216    video_dds           false
    00:00:15 216    video_decoder       FFmpegVideoDecoder
    00:00:15 216    info                Selected FFmpegVideoDecoder for video decoding, config: codec: vp8 format: 1 profile: vp8 coded size: [1280,720] visible rect: [0,0,1280,720] natural size: [1280,720] has extra data? false encryption scheme: Unencrypted rotation: 0°
    00:00:15 216    pipeline_state      kPlaying
    00:00:15 213    duration            unknown
    00:00:16 661    height              720
    00:00:16 661    width               1280
    00:00:16 665    video_buffering_state       BUFFERING_HAVE_ENOUGH
    00:00:16 665    for_suspended_start         false
    00:00:16 665    pipeline_buffering_state    BUFFERING_HAVE_ENOUGH
    00:00:16 667    pipeline_state      kSuspending
    00:00:16 670    pipeline_state      kSuspended
    00:00:52 759    info                Effective playback rate changed from 0 to 1
    00:00:52 759    event               PLAY
    00:00:52 759    pipeline_state      kResuming
    00:00:52 760    video_dds           false
    00:00:52 760    video_decoder       FFmpegVideoDecoder
    00:00:52 760    info                Selected FFmpegVideoDecoder for video decoding, config: codec: vp8 format: 1 profile: vp8 coded size: [1280,720] visible rect: [0,0,1280,720] natural size: [1280,720] has extra data? false encryption scheme: Unencrypted rotation: 0°
    00:00:52 760    pipeline_state      kPlaying
    00:00:52 793    height              720
    00:00:52 793    width               1280
    00:00:52 798    video_buffering_state       BUFFERING_HAVE_ENOUGH
    00:00:52 798    for_suspended_start         false
    00:00:52 798    pipeline_buffering_state    BUFFERING_HAVE_ENOUGH
    00:00:56 278    video_buffering_state       BUFFERING_HAVE_NOTHING
    00:00:56 295    for_suspended_start         false
    00:00:56 295    pipeline_buffering_state    BUFFERING_HAVE_NOTHING
    00:01:20 717    event               PAUSE
    00:01:33 538    event               PLAY
    00:01:35 94     event               PAUSE
    00:01:55 561    pipeline_state      kSuspending
    00:01:55 563    pipeline_state      kSuspended

    Can someone tell me what’s wrong with my code, or dose chrome require some magic configuration to work ?

    Thanks 

    Please excuse my english :)

  • Error : ffmpeg : Failed to download resource "sqlite"

    22 février 2023, par nour

    i am trying to download ffmpeg but I am getting this error ! could anyone help ? I am using paperclip gem to add images and videos. I am getting this error on heroku when i try to add a new video Av::UnableToDetect (Unable to detect any supported library so that's why im trying to download ffmpeg. could someone help please ! thanks in advance

    &#xA;

    brew install ffmpeg

    &#xA;

    curl: (60) SSL certificate problem: certificate has expired&#xA;More details here: https://curl.haxx.se/docs/sslcerts.html&#xA;&#xA;curl performs SSL certificate verification by default, using a "bundle"&#xA; of Certificate Authority (CA) public keys (CA certs). If the default&#xA; bundle file isn&#x27;t adequate, you can specify an alternate file&#xA; using the --cacert option.&#xA;If this HTTPS server uses a certificate signed by a CA represented in&#xA; the bundle, the certificate verification probably failed due to a&#xA; problem with the certificate (it might be expired, or the name might&#xA; not match the domain name in the URL).&#xA;If you&#x27;d like to turn off curl&#x27;s verification of the certificate, use&#xA; the -k (or --insecure) option.&#xA;HTTPS-proxy has similar options --proxy-cacert and --proxy-insecure.&#xA;Error: ffmpeg: Failed to download resource "sqlite"&#xA;Download failed: https://sqlite.org/2022/sqlite-autoconf-3400100.tar.gz&#xA;

    &#xA;

    when i add a new video to my website on heroku I got this error

    &#xA;

    2023-02-22T06:23:03.207072&#x2B;00:00 app[web.1]: User Load (0.8ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]&#xA;2023-02-22T06:23:03.208471&#x2B;00:00 app[web.1]: Steptation Load (0.7ms)  SELECT  "steptations".* FROM "steptations" WHERE "steptations"."id" = $1 LIMIT 1  [["id", 1802]]&#xA;2023-02-22T06:23:03.210118&#x2B;00:00 app[web.1]: [paperclip] Trying to link /tmp/RackMultipart20230222-2-1i28xon.mp4 to /tmp/847606d3771b12aa2d91db7647fe3a4920230222-2-165fycl.mp4&#xA;2023-02-22T06:23:03.210923&#x2B;00:00 app[web.1]: [paperclip] Trying to link /tmp/847606d3771b12aa2d91db7647fe3a4920230222-2-165fycl.mp4 to /tmp/847606d3771b12aa2d91db7647fe3a4920230222-2-p6icfm.mp4&#xA;2023-02-22T06:23:03.211217&#x2B;00:00 app[web.1]: Command :: file -b --mime &#x27;/tmp/847606d3771b12aa2d91db7647fe3a4920230222-2-p6icfm.mp4&#x27;&#xA;2023-02-22T06:23:03.218799&#x2B;00:00 app[web.1]: [AV] Running command: if command -v avprobe 2>/dev/null; then echo "true"; else echo "false"; fi&#xA;2023-02-22T06:23:03.221000&#x2B;00:00 app[web.1]: [AV] Running command: if command -v ffmpeg 2>/dev/null; then echo "true"; else echo "false"; fi&#xA;2023-02-22T06:23:03.222208&#x2B;00:00 heroku[router]: at=info method=POST path= "/step_images?id=1802" host=www.mobileimplantlab.ca request_id=39f2b001-ab36-4a59-ae94-1f300d386a40 fwd="207.216.102.221" dyno=web.1 connect=0ms service=900ms status=500 bytes=234 protocol=https&#xA;2023-02-22T06:23:03.222987&#x2B;00:00 app[web.1]: Completed 500 Internal Server Error in 18ms (ActiveRecord: 1.6ms)&#xA;2023-02-22T06:23:03.223510&#x2B;00:00 app[web.1]: &#xA;2023-02-22T06:23:03.223511&#x2B;00:00 app[web.1]: Av::UnableToDetect (Unable to detect any supported library):&#xA;2023-02-22T06:23:03.223511&#x2B;00:00 app[web.1]: app/controllers/step_images_controller.rb:15:in `create&#x27;&#xA;2023-02-22T06:23:03.223512&#x2B;00:00 app[web.1]: &#xA;2023-02-22T06:23:03.223512&#x2B;00:00 app[web.1]: &#xA;2023-02-22T06:23:14.356278&#x2B;00:00 app[web.1]: Started POST "/step_images?id=1802" for 207.216.102.221 at 2023-02-22 06:23:14 &#x2B;0000&#xA;2023-02-22T06:23:14.357993&#x2B;00:00 app[web.1]: Processing by StepImagesController#create as HTML&#xA;2023-02-22T06:23:14.358067&#x2B;00:00 app[web.1]: Parameters: {"utf8"=>"✓", "authenticity_token"=>"PgRtPGgyOSPP8lQlbf9fAgOSZre/XlYcKBKJhe81oOz9Ge81GZZzEfc4Xcnz0zzZ35S7PpsfKOse3Q73mxhjEA==", "step_image"=>{"product_id"=>"4", "text"=>"", "text2"=>"", "text3"=>"", "text4"=>"", "text5"=>"", "video"=>#, @original_filename="IMG_2826.mp4", @content_type="video/mp4", @headers="Content-Disposition: form-data; name=\"step_image[video]\"; filename=\"IMG_2826.mp4\"\r\nContent-Type: video/mp4\r\n">, "text6"=>"test", "user_id"=>"73", "case_id"=>"311", "step_id"=>"3"}, "commit"=>"Submit", "id"=>"1802"}&#xA;2023-02-22T06:23:14.359735&#x2B;00:00 app[web.1]: User Load (0.8ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]&#xA;2023-02-22T06:23:14.360954&#x2B;00:00 app[web.1]: Steptation Load (0.7ms)  SELECT  "steptations".* FROM "steptations" WHERE "steptations"."id" = $1 LIMIT 1  [["id", 1802]]&#xA;2023-02-22T06:23:14.362132&#x2B;00:00 app[web.1]: [paperclip] Trying to link /tmp/RackMultipart20230222-2-1stq4d4.mp4 to /tmp/847606d3771b12aa2d91db7647fe3a4920230222-2-1jq0dqp.mp4&#xA;2023-02-22T06:23:14.362719&#x2B;00:00 app[web.1]: [paperclip] Trying to link /tmp/847606d3771b12aa2d91db7647fe3a4920230222-2-1jq0dqp.mp4 to /tmp/847606d3771b12aa2d91db7647fe3a4920230222-2-9hfi7z.mp4&#xA;2023-02-22T06:23:14.362932&#x2B;00:00 app[web.1]: Command :: file -b --mime &#x27;/tmp/847606d3771b12aa2d91db7647fe3a4920230222-2-9hfi7z.mp4&#x27;&#xA;2023-02-22T06:23:14.370045&#x2B;00:00 app[web.1]: [AV] Running command: if command -v avprobe 2>/dev/null; then echo "true"; else echo "false"; fi&#xA;2023-02-22T06:23:14.372073&#x2B;00:00 app[web.1]: [AV] Running command: if command -v ffmpeg 2>/dev/null; then echo "true"; else echo "false"; fi&#xA;2023-02-22T06:23:14.374070&#x2B;00:00 app[web.1]: Completed 500 Internal Server Error in 16ms (ActiveRecord: 1.5ms)&#xA;2023-02-22T06:23:14.374254&#x2B;00:00 heroku[router]: at=info method=POST path= "/step_images?id=1802" host=www.mobileimplantlab.ca request_id=4a0702a2-8d14-454a-9f1f-edf154e140fc fwd="207.216.102.221" dyno=web.1 connect=0ms service=267ms status=500 bytes=234 protocol=https&#xA;2023-02-22T06:23:14.374720&#x2B;00:00 app[web.1]: &#xA;2023-02-22T06:23:14.374721&#x2B;00:00 app[web.1]: Av::UnableToDetect (Unable to detect any supported library):&#xA;

    &#xA;

    in my gem file

    &#xA;

    source &#x27;https://rubygems.org&#x27;&#xA;&#xA;&#xA;# Bundle edge Rails instead: gem &#x27;rails&#x27;, github: &#x27;rails/rails&#x27;&#xA;gem &#x27;rails&#x27;, &#x27;4.2.11.1&#x27;&#xA;# Use postgresql as the database for Active Record&#xA;gem &#x27;pg&#x27;, &#x27;~> 0.20.0&#x27;&#xA;# Use SCSS for stylesheets&#xA;gem &#x27;sass-rails&#x27;, &#x27;~> 5.0&#x27;&#xA;# Use Uglifier as compressor for JavaScript assets&#xA;gem &#x27;uglifier&#x27;, &#x27;>= 1.3.0&#x27;&#xA;# Use CoffeeScript for .coffee assets and views&#xA;gem &#x27;coffee-rails&#x27;, &#x27;~> 4.1.0&#x27;&#xA;# See https://github.com/rails/execjs#readme for more supported runtimes&#xA;# gem &#x27;therubyracer&#x27;, platforms: :ruby&#xA;gem &#x27;pry&#x27;, &#x27;~> 0.13.1&#x27;&#xA;# Use jquery as the JavaScript library&#xA;gem &#x27;jquery-rails&#x27;&#xA;# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks&#xA;gem &#x27;turbolinks&#x27;&#xA;# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder&#xA;gem &#x27;jbuilder&#x27;, &#x27;~> 2.0&#x27;&#xA;# bundle exec rake doc:rails generates the API under doc/api.&#xA;gem &#x27;sdoc&#x27;, &#x27;~> 0.4.0&#x27;, group: :doc&#xA;&#xA;# Use ActiveModel has_secure_password&#xA;# gem &#x27;bcrypt&#x27;, &#x27;~> 3.1.7&#x27;&#xA;&#xA;# Use Unicorn as the app server&#xA;# gem &#x27;unicorn&#x27;&#xA;&#xA;# Use Capistrano for deployment&#xA;# gem &#x27;capistrano-rails&#x27;, group: :development&#xA;&#xA;&#xA;group :development do&#xA;  # Access an IRB console on exception pages or by using &lt;%= console %> in views&#xA;  gem &#x27;web-console&#x27;, &#x27;~> 2.0&#x27;&#xA;&#xA;  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring&#xA;  gem &#x27;spring&#x27;&#xA;end&#xA;&#xA;gem &#x27;devise&#x27;&#xA;group :development, :test do&#xA;  gem "interactive_editor"&#xA;  gem "hirb"&#xA;  gem "awesome_print"&#xA;  gem &#x27;byebug&#x27;&#xA;end&#xA;group :production do&#xA;  gem &#x27;rails_12factor&#x27;&#xA;  gem &#x27;puma&#x27;&#xA;end&#xA;gem &#x27;mail_form&#x27;&#xA;gem &#x27;font-awesome-sass&#x27;, &#x27;~> 5.12.0&#x27;&#xA;&#xA;gem &#x27;bootsnap&#x27;, &#x27;>= 1.1.0&#x27;, require: false&#xA;gem &#x27;bootstrap-sass&#x27;, &#x27;~>3.2.0&#x27;&#xA;&#xA;gem &#x27;paperclip&#x27;&#xA;&#xA;gem &#x27;aws-sdk-s3&#x27;&#xA;gem &#x27;aws-sdk&#x27;, &#x27;&lt; 2.0&#x27;&#xA;&#xA;gem &#x27;thor&#x27;, &#x27;0.19.1&#x27;&#xA;gem &#x27;omniauth-google-oauth2&#x27;&#xA;gem "recaptcha", require: "recaptcha/rails"&#xA;gem &#x27;friendly_id&#x27;, &#x27;~> 5.4.0&#x27;&#xA;&#xA;gem &#x27;activeadmin&#x27;&#xA;&#xA;gem &#x27;cocoon&#x27;&#xA;gem &#x27;bigdecimal&#x27;, &#x27;1.3.5&#x27;&#xA;gem &#x27;bundler&#x27;, &#x27;1.17.3&#x27;&#xA;gem &#x27;paperclip-av-transcoder&#x27;&#xA;gem "paperclip-ffmpeg", "~> 1.2.0"&#xA;gem "will_paginate", "~> 3.0.4" &#xA;gem &#x27;rails-erd&#x27;&#xA;gem &#x27;rails_autolink&#x27;&#xA;&#xA;gem &#x27;rails-erd&#x27;, group: :development&#xA;

    &#xA;

    in the model

    &#xA;

      has_attached_file :video, :styles => {&#xA;     :medium => { :geometry => "500x500", :format => &#x27;jpg&#x27; },&#xA;     :thumb => { :geometry => "100x100", :format => &#x27;jpg&#x27; }&#xA;  }, :processors => [:transcoder]&#xA;&#xA;  validates_attachment_content_type :video,&#xA;    :content_type => [&#xA;      "video/mp4", &#xA;      "video/quicktime",&#xA;      "video/3gpp",&#xA;      "video/x-ms-wmv",&#xA;      "video/mov",&#xA;      "video/flv",&#xA;      &#xA;      ]&#xA;

    &#xA;