Created
March 12, 2017 22:19
-
-
Save protyposis/a9dc703a9107222a09f40dd0b2afff6d to your computer and use it in GitHub Desktop.
MediaPlayer-Extended Workaround for Samsung libstagefright bug with JPEG thumbnail tracks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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