Exemple #1
0
    private static unsafe void DrawWaves(ThumbnailsRenderContext ctx, MediaStream audioStream)
    {
        var height = 88;
        var width  = 88;

        using var recorder = new SKPictureRecorder();
        using var canvas   = recorder.BeginRecording(SKRect.Create(width, height));
        var columnCount = 88 * 2;
        var columnWidth = (float)width / columnCount;

        using var wavePaint = new SKPaint { Color = new SKColor(128, 128, 128, 76), StrokeWidth = columnWidth };
        var totalSample     = audioStream.SampleRate * audioStream.Duration;
        var columnMaxSample = (int)(totalSample / columnCount);
        var columns         = new short[columnCount];

        using var decoder = audioStream.CreateStreamDecoder();
        using var filter  = new AudioFormatFilter("sample_fmts=s16:channel_layouts=mono", audioStream, decoder);
        filter.Build();

        long sum = 0;
        var  n   = 0;
        var  c   = 0;

        while (filter.MoveNext())
        {
            var frame = filter.Current.Value;
            var p     = (short *)frame->data[0];

            for (var i = 0; i < frame->nb_samples; i++)
            {
                sum += SampleAbs(p[i]);

                n++;
                if (n == columnMaxSample && c < columnCount)
                {
                    columns[c] = (short)(sum / n);

                    n   = 0;
                    sum = 0;
                    c++;
                }
            }
        }

        for (var i = 0; i < columnCount; i++)
        {
            var h = Math.Max((float)columns[i] * height / short.MaxValue, 0.5f);
            var x = i * columnWidth;
            canvas.DrawLine(x, (height - h) / 2.0f, x, (height + h) / 2.0f, wavePaint);
        }

        _cachedWaveformDecorationImage ??= SKImage.FromEncodedData(ReadWaveformDecorationImage());
        canvas.DrawImage(_cachedWaveformDecorationImage, SKRect.Create((width - 28) / 2.0f, (height - 36) / 2.0f, 28, 36));

        using var picture = recorder.EndRecording();
        ThumbnailUtils.DrawShadowView(
            ctx,
            new SkPictureView(
                picture,
                new SKSize(88, 88)));
    }