linkedin / linkedin/LiTr

Unable to overlay audio over video

Open
#250 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
663
Forks
92
PR merge metrics
No merged PRs in 30d

Description

I want to work with following feature in our app

1) set Resolution , bitrate, FRAME_INTERVAL, FRAME_RATE, for video
2) set CHANNEL_COUNT,SAMPLE_RATE,KEY_BIT_RATE for audio
3) set duration for Audio and video
4) overlay audio over video

My video has audio and the audio file should overlay over it

I am trying this code

```
public class MainActivity extends AppCompatActivity {

MediaMuxerMediaTarget mediaTarget;
MediaExtractorMediaSource videoMediaSource, audioMediaSource;
Uri sourceVideoUri = Uri.parse("content://media/external/video/media/1000000034");
Uri sourceAudioUri = Uri.parse("content://media/external/audio/media/53");

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frag2);
// common target
String outputPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/vidos1.mp4";
File file = new File(outputPath);
if (file.exists()) {
file.delete();
}
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
mediaTarget = new MediaMuxerMediaTarget(outputPath, 2, 0, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
} catch (MediaTargetException e) {
throw new RuntimeException(e);
}
try {
videoMediaSource = new MediaExtractorMediaSource(MainActivity.this, sourceVideoUri);
MediaRange mediaRange;
mediaRange = new MediaRange(0, getMediaDuration(sourceVideoUri));
audioMediaSource = new MediaExtractorMediaSource(MainActivity.this, sourceAudioUri, mediaRange);
} catch (MediaSourceException e) {
throw new RuntimeException(e);
}
// video track config
MediaFormat targetVideoFormat = MediaFormat.createVideoFormat("video/avc", 1280, 720); // assuming 720p landscape video
targetVideoFormat.setInteger(MediaFormat.KEY_BIT_RATE, 5_000_000);
targetVideoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 3);
targetVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
targetVideoFormat.setInteger(KEY_ROTATION, 0);
// video track transform
TrackTransform videoTrackTransform = new TrackTransform.Builder(videoMediaSource, 0, mediaTarget) // assuming that video track index in source file is 0
.setTargetTrack(0)
.setDecoder(new MediaCodecDecoder())
.setEncoder(new MediaCodecEncoder())
.setRenderer(new GlVideoRenderer(null))
.setTargetFormat(targetVideoFormat)
.build();
// audio track transform
Encoder encoder = new MediaCodecEncoder();
TrackTransform audioTrackTransform = new TrackTransform.Builder(audioMediaSource, 0, mediaTarget) // assuming that audio track index in source file is 0
.setTargetTrack(1)
.setDecoder(new MediaCodecDecoder())
.setEncoder(encoder)
.setTargetFormat(createAudioMediaFormat())
.setRenderer(
new AudioRenderer(
encoder,
Collections.singletonList(new AudioOverlayFilter(MainActivity.this, sourceAudioUri))
))
.build();
TransformationListener listener = new TransformationListener() {

@Override
public void onStarted(String id) {
// TODO: Implement this method
Toast.makeText(MainActivity.this, "Started ", Toast.LENGTH_SHORT).show();
}

@Override
public void onProgress(String id, float progress) {
// TODO: Implement this method
Toast.makeText(MainActivity.this, "progress " + progress, Toast.LENGTH_SHORT).show();
}

@Override
public void onCompleted(String id, List trackTransformationInfos) {
//sm("ok");
Toast.makeText(MainActivity.this, "Completed ", Toast.LENGTH_SHORT).show();
}

@Override
public void onCancelled(String id, List trackTransformationInfos) {
// TODO: Implement this method
}

@Override
public void onError(String id, Throwable cause, List trackTransformationInfos) {
// sm("error=" + id);
Log.e(TAG, "error= eeeeeeeeeeeeeeeeeee" + cause);
Toast.makeText(MainActivity.this, "error=" + cause, Toast.LENGTH_SHORT).show();
}
};
Button TransFormButton = (Button) findViewById(R.id.TransformButton);
TransFormButton.setOnClickListener(view -> {
MediaTransformer mediaTransformer = new MediaTransformer(getApplicationContext());
List trackTransforms = new ArrayList<>();
trackTransforms.add(videoTrackTransform);
trackTransforms.add(audioTrackTransform);
mediaTransformer.transform(
"663201",
trackTransforms,
listener,
MediaTransformer.GRANULARITY_DEFAULT);
});
}

@NonNull
private MediaFormat createAudioMediaFormat() {
MediaFormat mediaFormat = new MediaFormat();
for (int i = 0; i < audioMediaSource.getTrackCount(); i++) {
MediaFormat trackFormat = audioMediaSource.getTrackFormat(i);
mediaFormat.setString(MediaFormat.KEY_MIME, AUDIO_AAC);
mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, trackFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, trackFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, trackFormat.getInteger(MediaFormat.KEY_BIT_RATE));
mediaFormat.setLong(MediaFormat.KEY_DURATION, getMediaDuration(sourceVideoUri));
}
return mediaFormat;
}

private long getMediaDuration(@NonNull Uri uri) {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(MainActivity.this, uri);
String durationStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
return Long.parseLong(durationStr);
}
}
```

However the overlay doesnot work even the original audio from video file is removed.

When we remove the

```
.setRenderer(
new AudioRenderer(
encoder,
Collections.singletonList(new AudioOverlayFilter(MainActivity.this, sourceAudioUri))
))
```

It replaces the audio of video with the audio from audio file.

How can we keep original audio and overlay new audio over it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in the provided MainActivity flow and trace AudioRenderer, AudioOverlayFilter, and both TrackTransform configurations to determine why the overlay path removes the source audio. Use the reported output behavior as the reproduction; done means the generated video retains its original audio while the selected audio file is mixed over it.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
audio-video-rtc, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.