コード例 #1
0
        protected override void OnCreate(Bundle savedInstanceState)
        {
            context = this;

            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            SetContentView(Resource.Layout.activity_main);

            var toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
            SetSupportActionBar(toolbar);

            var processButton = FindViewById<Button>(Resource.Id.processButton);
            processButton.Click += ProcessButton_Click;

            _playerView = FindViewById<PlayerView>(Resource.Id.playerView);

            _sourceMedia = new SourceMedia();
            _targetMedia = new TargetMedia();
            _transformationState = new TransformationState();
            _trimConfig = new TrimConfig();

            _mediaTransformer = new MediaTransformer(this);


            var builder = new SimpleExoPlayer.Builder(this);
            _player = builder.Build();

            _player.PlayWhenReady = true;
            _playerView.Player = _player;
        }
コード例 #2
0
        protected void updateSourceMedia(SourceMedia sourceMedia, Android.Net.Uri uri)
        {
            sourceMedia.uri = uri;
            sourceMedia.size = TranscoderUtils.GetSize(this, uri);
            sourceMedia.duration = getMediaDuration(uri) / 1000f;

            try
            {
                MediaExtractor mediaExtractor = new MediaExtractor();
                mediaExtractor.SetDataSource(this, uri, null);
                sourceMedia.tracks = new List<MediaTrackFormat>(mediaExtractor.TrackCount);

                for (int track = 0; track < mediaExtractor.TrackCount; track++)
                {
                    MediaFormat mediaFormat = mediaExtractor.GetTrackFormat(track);
                    var mimeType = mediaFormat.GetString(MediaFormat.KeyMime);
                    if (mimeType == null)
                    {
                        continue;
                    }

                    if (mimeType.StartsWith("video"))
                    {
                        VideoTrackFormat videoTrack = new VideoTrackFormat(track, mimeType);
                        videoTrack.width = getInt(mediaFormat, MediaFormat.KeyWidth);
                        videoTrack.height = getInt(mediaFormat, MediaFormat.KeyHeight);
                        videoTrack.duration = getLong(mediaFormat, MediaFormat.KeyDuration);
                        videoTrack.frameRate = MediaFormatUtils.GetFrameRate(mediaFormat, new Java.Lang.Integer(-1)).IntValue();
                        videoTrack.keyFrameInterval = MediaFormatUtils.GetIFrameInterval(mediaFormat, new Java.Lang.Integer(-1)).IntValue();
                        videoTrack.rotation = getInt(mediaFormat, TrackMetadataUtil.KEY_ROTATION, 0);
                        videoTrack.bitrate = getInt(mediaFormat, MediaFormat.KeyBitRate);
                        sourceMedia.tracks.Add(videoTrack);
                    }
                    else if (mimeType.StartsWith("audio"))
                    {
                        AudioTrackFormat audioTrack = new AudioTrackFormat(track, mimeType);
                        audioTrack.channelCount = getInt(mediaFormat, MediaFormat.KeyChannelCount);
                        audioTrack.samplingRate = getInt(mediaFormat, MediaFormat.KeySampleRate);
                        audioTrack.duration = getLong(mediaFormat, MediaFormat.KeyDuration);
                        audioTrack.bitrate = getInt(mediaFormat, MediaFormat.KeyBitRate);
                        sourceMedia.tracks.Add(audioTrack);
                    }
                    else
                    {
                        sourceMedia.tracks.Add(new GenericTrackFormat(track, mimeType));
                    }
                }
            }
            catch (IOException ex)
            {
                System.Diagnostics.Debug.WriteLine($"Failed to extract sourceMedia: {ex.Message}");
            }

            sourceMedia.NotifyChange();
        }
コード例 #3
0
        private List<IGlFilter> createGlFilters(SourceMedia sourceMedia,
                                           TargetVideoTrack targetTrack,
                                           float overlayWidth,
                                           PointF position,
                                           float rotation)
        {
            List<IGlFilter> glFilters = null;
            if (targetTrack != null && targetTrack.overlay != null)
            {
                try
                {
                    Bitmap bitmap = BitmapFactory.DecodeStream(context.ContentResolver.OpenInputStream(targetTrack.overlay));
                    if (bitmap != null)
                    {
                        float overlayHeight;
                        VideoTrackFormat sourceVideoTrackFormat = (VideoTrackFormat)sourceMedia.tracks[targetTrack.sourceTrackIndex];
                        if (sourceVideoTrackFormat.rotation == 90 || sourceVideoTrackFormat.rotation == 270)
                        {
                            float overlayWidthPixels = overlayWidth * sourceVideoTrackFormat.height;
                            float overlayHeightPixels = overlayWidthPixels * bitmap.Height / bitmap.Width;
                            overlayHeight = overlayHeightPixels / sourceVideoTrackFormat.width;
                        }
                        else
                        {
                            float overlayWidthPixels = overlayWidth * sourceVideoTrackFormat.width;
                            float overlayHeightPixels = overlayWidthPixels * bitmap.Height / bitmap.Width;
                            overlayHeight = overlayHeightPixels / sourceVideoTrackFormat.height;
                        }

                        PointF size = new PointF(overlayWidth, overlayHeight);

                        IGlFilter filter = TransformationUtil.createGlFilter(context,
                                                                            targetTrack.overlay,
                                                                            size,
                                                                            position,
                                                                            rotation);
                        if (filter != null)
                        {
                            glFilters = new List<IGlFilter>();
                            glFilters.Add(filter);
                        }
                    }
                }
                catch (System.Exception err)
                {
                    System.Diagnostics.Debug.WriteLine($"Failed to extract audio track metadata: {err.Message}");
                }
            }

            return glFilters;
        }
コード例 #4
0
 public async void Delete(SourceMedia media)
 {
     File.Delete(media.Reference);
 }
コード例 #5
0
        public void TranscodeAudio(SourceMedia sourceMedia,
                              TargetMedia targetMedia,
                              TrimConfig trimConfig,
                              TransformationState transformationState)
        {


            if (targetMedia.targetFile.Exists())
            {
                targetMedia.targetFile.Delete();
            }

            transformationState.requestId = UUID.RandomUUID().ToString();

            /*
            MediaTransformationListener transformationListener = new MediaTransformationListener(context,
                    transformationState.requestId,
                    transformationState,
                    targetMedia);
            */

            MediaRange mediaRange = trimConfig.enabled
                    ? new MediaRange(
                    TimeUnit.Milliseconds.ToMicros((long)(trimConfig.range[0] * 1000)),
                    TimeUnit.Milliseconds.ToMicros((long)(trimConfig.range[1] * 1000)))
                    : new MediaRange(0, long.MaxValue);

            try
            {
                var targetMimeType = targetMedia.writeToWav ? "audio/raw" : "audio/mp4a-latm";
                IMediaTarget mediaTarget;

                if (targetMedia.writeToWav)
                {
                    mediaTarget = new WavMediaTarget(targetMedia.targetFile.Path);
                }
                else
                {
                    mediaTarget = new MediaMuxerMediaTarget(targetMedia.targetFile.Path, 1, 0, (int)MuxerOutputType.Mpeg4);
                }
                var mediaSource = new MediaExtractorMediaSource(context, sourceMedia.uri, mediaRange);
                List<TrackTransform> trackTransforms = new List<TrackTransform>(1);

                foreach (TargetTrack targetTrack in targetMedia.tracks)
                { 
                    if (targetTrack.format is AudioTrackFormat trackFormat)
                    {
                        MediaFormat mediaFormat = MediaFormat.CreateAudioFormat(
                                targetMimeType,
                                trackFormat.samplingRate,
                                trackFormat.channelCount);
                        mediaFormat.SetInteger(MediaFormat.KeyBitRate, trackFormat.bitrate);
                        mediaFormat.SetLong(MediaFormat.KeyDuration, trackFormat.duration);

                        IEncoder encoder;
                        if (targetMedia.writeToWav)
                        {
                            encoder = new PassthroughBufferEncoder(8192);
                        }
                        else
                        {
                            encoder = new MediaCodecEncoder();
                        }
                        //IEncoder encoder = targetMedia.writeToWav ? new PassthroughBufferEncoder(8192) : new MediaCodecEncoder();
                        TrackTransform trackTransform = new TrackTransform.Builder(mediaSource, targetTrack.sourceTrackIndex, mediaTarget)
                                .SetTargetTrack(0)
                                .SetDecoder(new MediaCodecDecoder())
                                .SetEncoder(encoder)
                                .SetRenderer(new AudioRenderer(encoder))
                                .SetTargetFormat(mediaFormat)
                                .Build();


                        trackTransforms.Add(trackTransform);
                        break;
                    }
                }

                _mediaTransformer.Transform(
                    transformationState.requestId,
                    trackTransforms,
                    this,
                    MediaTransformer.GranularityDefault);
            }
            catch (System.Exception err)
            {
                System.Diagnostics.Debug.WriteLine($"Exception when trying to transcode audio: {err.Message}");
            }
        }
コード例 #6
0
        void ApplyWatermark(SourceMedia sourceMedia,
                              TargetMedia targetMedia,
                              TrimConfig trimConfig,
                              TransformationState transformationState)
        {
            if (targetMedia.targetFile.Exists())
            {
                targetMedia.targetFile.Delete();
            }

            transformationState.requestId = UUID.RandomUUID().ToString();

            /*
            MediaTransformationListener transformationListener = new MediaTransformationListener(this,
                    transformationState.requestId,
                    transformationState,
                    targetMedia);
            */

            var resourceId = Resource.Drawable.test_image_1;
            var watermarkUri = new Uri.Builder()
                .Scheme(ContentResolver.SchemeAndroidResource)
                .Authority(Resources.GetResourcePackageName(resourceId))
                .AppendPath(Resources.GetResourceTypeName(resourceId))
                .AppendPath(Resources.GetResourceEntryName(resourceId))
                .Build();



            List<IGlFilter> watermarkImageFilter = null;
            foreach (TargetTrack targetTrack in targetMedia.tracks)
            {

                if (targetTrack is TargetVideoTrack targetVideoTrack) 
                {
                    targetVideoTrack.overlay = watermarkUri;

                    watermarkImageFilter = createGlFilters(
                        sourceMedia,
                        (TargetVideoTrack)targetTrack,
                        0.2f,
                        new PointF(0.8f, 0.8f),
                        0);
                    break;
                }
            }

            
            MediaRange mediaRange = trimConfig.enabled
                    ? new MediaRange(
                    TimeUnit.Milliseconds.ToMicros((long)(trimConfig.range[0] * 1000)),
                    TimeUnit.Milliseconds.ToMicros((long)(trimConfig.range[1] * 1000)))
                    : new MediaRange(0, long.MaxValue);
            TransformationOptions transformationOptions = new TransformationOptions.Builder()
                    .SetGranularity(MediaTransformer.GranularityDefault)
                    .SetVideoFilters(watermarkImageFilter)
                    .SetSourceMediaRange(mediaRange)
                    .Build();

            _mediaTransformer.Transform(
                    _transformationState.requestId,
                    _sourceMedia.uri,
                    targetMedia.targetFile.Path,
                    null,
                    null,
                    this,
                    transformationOptions);
      

        }
コード例 #7
0
        private bool _do()
        {
            AddOutputMessage($"Operation {Title} started");
            StartTime       = DateTime.UtcNow;
            OperationStatus = FileOperationStatus.InProgress;
            switch (Kind)
            {
            case TFileOperationKind.None:
                return(true);

            case TFileOperationKind.Convert:
            case TFileOperationKind.Export:
                throw new InvalidOperationException("Invalid operation kind");

            case TFileOperationKind.Copy:
                if (_sourceMedia != null && File.Exists(_sourceMedia.FullPath) && Directory.Exists(DestDirectory.Folder))
                {
                    try
                    {
                        CreateDestMediaIfNotExists();
                        if (!(_destMedia.FileExists() &&
                              File.GetLastWriteTimeUtc(_sourceMedia.FullPath).Equals(File.GetLastWriteTimeUtc(_destMedia.FullPath)) &&
                              File.GetCreationTimeUtc(_sourceMedia.FullPath).Equals(File.GetCreationTimeUtc(_destMedia.FullPath)) &&
                              SourceMedia.FileSize.Equals(_destMedia.FileSize)))
                        {
                            _destMedia.MediaStatus = TMediaStatus.Copying;
                            IsIndeterminate        = true;
                            if (!((Media)SourceMedia).CopyMediaTo((Media)_destMedia, ref _aborted))
                            {
                                return(false);
                            }
                        }
                        _destMedia.MediaStatus = TMediaStatus.Copied;
                        ThreadPool.QueueUserWorkItem(o => ((Media)_destMedia).Verify());
                        AddOutputMessage($"Copy operation {Title} finished");
                        return(true);
                    }
                    catch (Exception e)
                    {
                        AddOutputMessage($"Copy operation {Title} failed with {e.Message}");
                    }
                }
                return(false);

            case TFileOperationKind.Delete:
                try
                {
                    if (SourceMedia.Delete())
                    {
                        AddOutputMessage($"Delete operation {Title} finished");
                        return(true);
                    }
                }
                catch (Exception e)
                {
                    AddOutputMessage($"Delete operation {Title} failed with {e.Message}");
                }
                return(false);

            case TFileOperationKind.Move:
                if (File.Exists(_sourceMedia.FullPath) && Directory.Exists(DestDirectory.Folder))
                {
                    try
                    {
                        CreateDestMediaIfNotExists();
                        if (_destMedia.FileExists())
                        {
                            if (File.GetLastWriteTimeUtc(_sourceMedia.FullPath).Equals(File.GetLastWriteTimeUtc(_destMedia.FullPath)) &&
                                File.GetCreationTimeUtc(_sourceMedia.FullPath).Equals(File.GetCreationTimeUtc(_destMedia.FullPath)) &&
                                _sourceMedia.FileSize.Equals(_destMedia.FileSize))
                            {
                                _sourceMedia.Delete();
                                return(true);
                            }
                            else
                            if (!_destMedia.Delete())
                            {
                                AddOutputMessage("Move operation failed - destination media not deleted");
                                return(false);
                            }
                        }
                        IsIndeterminate        = true;
                        _destMedia.MediaStatus = TMediaStatus.Copying;
                        FileUtils.CreateDirectoryIfNotExists(Path.GetDirectoryName(_destMedia.FullPath));
                        File.Move(_sourceMedia.FullPath, _destMedia.FullPath);
                        File.SetCreationTimeUtc(_destMedia.FullPath, File.GetCreationTimeUtc(_sourceMedia.FullPath));
                        File.SetLastWriteTimeUtc(_destMedia.FullPath, File.GetLastWriteTimeUtc(_sourceMedia.FullPath));
                        _destMedia.MediaStatus = TMediaStatus.Copied;
                        ThreadPool.QueueUserWorkItem(o => ((Media)_destMedia).Verify());
                        AddOutputMessage("Move operation finished");
                        Debug.WriteLine(this, "File operation succeed");
                        return(true);
                    }
                    catch (Exception e)
                    {
                        AddOutputMessage($"Move operation {Title} failed with {e.Message}");
                    }
                }
                return(false);

            default:
                return(false);
            }
        }