Skip to content

Instantly share code, notes, and snippets.

@protyposis
Created March 12, 2017 22:19
Show Gist options
  • Save protyposis/a9dc703a9107222a09f40dd0b2afff6d to your computer and use it in GitHub Desktop.
Save protyposis/a9dc703a9107222a09f40dd0b2afff6d to your computer and use it in GitHub Desktop.
MediaPlayer-Extended Workaround for Samsung libstagefright bug with JPEG thumbnail tracks
/*
* Copyright 2017 Mario Guggenberger <mg@protyposis.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.protyposis.android.mediaplayerdemo;
import android.os.Build;
import net.protyposis.android.mediaplayer.FileSource;
import net.protyposis.android.mediaplayer.MediaPlayer;
import net.protyposis.android.mediaplayer.MediaSource;
import net.protyposis.android.mediaplayer.UriSource;
import java.io.IOException;
public class MediaPlayerWorkarounds {
// public static void setVideoSource(VideoView videoView, MediaSource source) throws IOException {
public static void setDataSourceSamsung(MediaPlayer mediaPlayer, MediaSource source) throws IOException {
// Track selection workaround for Samsung devices. Some Samsung Android versions crash
// on JPEG tracks when enumerating tracks through the MediaExtractor:
//
// E/SampleTable: mNumSyncSamples error
// A/Utils: frameworks/av/media/libstagefright/Utils.cpp:105 CHECK(meta->findInt32(kKeyWidth, &width)) failed.
// A/libc: Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1)
//
// Android's MediaPlayer uses another API and does not crash, so we use a temporary
// instance to enumerate the tracks and determine the video and audio track indices.
if(Build.MANUFACTURER.toLowerCase().equals("samsung")
// No crash on 4.1.2, crash on 4.3, 4.2 untested, so we start with 4.2
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
// Crash on 4.4, 5.0/5.1 untested, no crash on 6.0.1, so we end with 5.1
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
android.media.MediaPlayer videoPlayer;
android.media.MediaPlayer audioPlayer = null;
int videoTrackIndex = MediaPlayer.TRACK_INDEX_NONE;
int audioTrackIndex = MediaPlayer.TRACK_INDEX_NONE;
if (source instanceof UriSource) {
UriSource uriSource = (UriSource) source;
videoPlayer = new android.media.MediaPlayer();
videoPlayer.setDataSource(uriSource.getContext(), uriSource.getUri(), uriSource.getHeaders());
if (uriSource.getAudioUri() != null) {
audioPlayer = new android.media.MediaPlayer();
audioPlayer.setDataSource(uriSource.getContext(), uriSource.getAudioUri(), uriSource.getAudioHeaders());
}
} else if (source instanceof FileSource) {
FileSource fileSource = (FileSource) source;
videoPlayer = new android.media.MediaPlayer();
videoPlayer.setDataSource(fileSource.getFile().getAbsolutePath());
if (fileSource.getAudioFile() != null) {
audioPlayer = new android.media.MediaPlayer();
audioPlayer.setDataSource(fileSource.getAudioFile().getAbsolutePath());
}
} else {
throw new IOException("Cannot feed " + source.getClass().getCanonicalName()
+ " into Android MediaPlayer");
}
int index = 0;
for (android.media.MediaPlayer.TrackInfo trackInfo : videoPlayer.getTrackInfo()) {
if (videoTrackIndex == MediaPlayer.TRACK_INDEX_NONE
&& trackInfo.getTrackType() == android.media.MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
videoTrackIndex = index;
} else if (audioTrackIndex == MediaPlayer.TRACK_INDEX_NONE
&& trackInfo.getTrackType() == android.media.MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
audioTrackIndex = index;
}
index++;
}
if (audioPlayer != null) {
index = 0;
for (android.media.MediaPlayer.TrackInfo trackInfo : videoPlayer.getTrackInfo()) {
if (trackInfo.getTrackType() == android.media.MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
audioTrackIndex = index;
break;
}
index++;
}
}
videoPlayer.release();
if(audioPlayer != null) {
audioPlayer.release();
}
// videoView.setVideoSource(source, videoTrackIndex, audioTrackIndex);
mediaPlayer.setDataSource(source, videoTrackIndex, audioTrackIndex);
} else {
// videoView.setVideoSource(source, videoTrackIndex, audioTrackIndex);
mediaPlayer.setDataSource(source);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment