deepmedia / Transcoder

🎞 Hardware-accelerated video transcoding using Android MediaCodec APIs. Supports cropping, concatenation, clipping, audio processing, video speed and much more.
https://opensource.deepmedia.io/transcoder
Apache License 2.0
783 stars 166 forks source link

Friendly API for changing speed of single video in a chain #141

Open pawaom opened 3 years ago

pawaom commented 3 years ago

I have 2 videos I want to keep Speed of First video to the original speed, i.e 1 and for the second video to double speed i.e 2,

The first video is 5 seconds long, and second video is 46 seconds long, So now the video should be 28 seconds long(5+23)

however the code converts both video to double speed ,

can we Set speed of Individual videos

This is the code I am trying

mProgressView = findViewById(R.id.progress);
        mProgressView.setMax(PROGRESS_BAR_MAX);
        try {
            File outputDir = new File(getExternalFilesDir(null), "outputs");
            //noinspection ResultOfMethodCallIgnored
            outputDir.mkdir();
            mTranscodeOutputFile = File.createTempFile("transcode_test", ".mp4", outputDir);
        } catch (IOException e) {
            Toast.makeText(this, "Failed to create temporary file.", Toast.LENGTH_LONG).show();
            return;
        }
        DataSink sink = new DefaultDataSink(mTranscodeOutputFile.getAbsolutePath());
        Transcoder.into(sink)
                .addDataSource(Environment.getExternalStorageDirectory() + "/Test_videos/c.mp4").
                setSpeed(1).
                addDataSource(Environment.getExternalStorageDirectory() + "/Test_videos/d.mp4").
                setSpeed(2).
                setListener(new TranscoderListener() {
            public void onTranscodeProgress(double progress) {
                if (progress < 0) {
                    mProgressView.setIndeterminate(true);
                } else {
                    mProgressView.setIndeterminate(false);
                    mProgressView.setProgress((int) Math.round(progress * PROGRESS_BAR_MAX));
                }
            }
            public void onTranscodeCompleted(int successCode) {
                if (successCode == Transcoder.SUCCESS_TRANSCODED) {
                    Toast.makeText(abcd.this, "Success ", Toast.LENGTH_SHORT).show();
                    mProgressView.setIndeterminate(false);
                    mProgressView.setProgress(0);
                } else if (successCode == Transcoder.SUCCESS_NOT_NEEDED) {

                }
            }
            public void onTranscodeCanceled() {}
            public void onTranscodeFailed(@NonNull Throwable exception) {}
                }).transcode();
pawaom commented 3 years ago

I did manage to get it working but Is there a better solution , can it be included in next release(I have worked only on Java code)

In Engine.java

 private void openCurrentStep(@NonNull TrackType type, @NonNull TranscoderOptions options) {
        int current = mCurrentStep.require(type);
        TrackStatus status = mStatuses.require(type);
        Log.e(TAG, "openCurrentStep #" + current );

        if (current == 0){
            options.SetLocalSpeed(1);
        }
        else{
            options.SetLocalSpeed(2);
        }

In TranscoderOptions.java

 @NonNull
    public void SetLocalSpeed(float t) {
        timeInterpolator = new SpeedTimeInterpolator(t);
    } 
yuyuan20 commented 3 years ago

Did you manage to get it working?

natario1 commented 2 months ago

(Pasted to all my answers today: it's been a long time since my last issues review. I am sorry about the delay and I know you likely have moved on by now. Still, I'm going to answer where I can)

This is possible with a custom TimeInterpolator where you return a different speed depending on the current position. However, we could definitely add a more friendly API for this.