Search in sources :

Example 16 with C

use of com.google.android.exoplayer2.C in project ExoPlayer by google.

the class HlsMediaChunk method peekId3PrivTimestamp.

/**
 * Peek the presentation timestamp of the first sample in the chunk from an ID3 PRIV as defined in
 * the HLS spec, version 20, Section 3.4. Returns {@link C#TIME_UNSET} if the frame is not found.
 * This method only modifies the peek position.
 *
 * @param input The {@link ExtractorInput} to obtain the PRIV frame from.
 * @return The parsed, adjusted timestamp in microseconds
 * @throws IOException If an error occurred peeking from the input.
 */
private long peekId3PrivTimestamp(ExtractorInput input) throws IOException {
    input.resetPeekPosition();
    try {
        scratchId3Data.reset(Id3Decoder.ID3_HEADER_LENGTH);
        input.peekFully(scratchId3Data.getData(), 0, Id3Decoder.ID3_HEADER_LENGTH);
    } catch (EOFException e) {
        // The input isn't long enough for there to be any ID3 data.
        return C.TIME_UNSET;
    }
    int id = scratchId3Data.readUnsignedInt24();
    if (id != Id3Decoder.ID3_TAG) {
        return C.TIME_UNSET;
    }
    // version(2), flags(1).
    scratchId3Data.skipBytes(3);
    int id3Size = scratchId3Data.readSynchSafeInt();
    int requiredCapacity = id3Size + Id3Decoder.ID3_HEADER_LENGTH;
    if (requiredCapacity > scratchId3Data.capacity()) {
        byte[] data = scratchId3Data.getData();
        scratchId3Data.reset(requiredCapacity);
        System.arraycopy(data, 0, scratchId3Data.getData(), 0, Id3Decoder.ID3_HEADER_LENGTH);
    }
    input.peekFully(scratchId3Data.getData(), Id3Decoder.ID3_HEADER_LENGTH, id3Size);
    Metadata metadata = id3Decoder.decode(scratchId3Data.getData(), id3Size);
    if (metadata == null) {
        return C.TIME_UNSET;
    }
    int metadataLength = metadata.length();
    for (int i = 0; i < metadataLength; i++) {
        Metadata.Entry frame = metadata.get(i);
        if (frame instanceof PrivFrame) {
            PrivFrame privFrame = (PrivFrame) frame;
            if (PRIV_TIMESTAMP_FRAME_OWNER.equals(privFrame.owner)) {
                System.arraycopy(privFrame.privateData, 0, scratchId3Data.getData(), 0, 8);
                scratchId3Data.setPosition(0);
                scratchId3Data.setLimit(8);
                // streaming provider forgot. See: https://github.com/google/ExoPlayer/pull/3495.
                return scratchId3Data.readLong() & 0x1FFFFFFFFL;
            }
        }
    }
    return C.TIME_UNSET;
}
Also used : EOFException(java.io.EOFException) Metadata(com.google.android.exoplayer2.metadata.Metadata) PrivFrame(com.google.android.exoplayer2.metadata.id3.PrivFrame)

Example 17 with C

use of com.google.android.exoplayer2.C in project ExoPlayer by google.

the class TestUtil method seekToTimeUs.

/**
 * Seeks to the given seek time of the stream from the given input, and keeps reading from the
 * input until we can extract at least one sample following the seek position, or until
 * end-of-input is reached.
 *
 * @param extractor The {@link Extractor} to extract from input.
 * @param seekMap The {@link SeekMap} of the stream from the given input.
 * @param seekTimeUs The seek time, in micro-seconds.
 * @param trackOutput The {@link FakeTrackOutput} to store the extracted samples.
 * @param dataSource The {@link DataSource} that will be used to read from the input.
 * @param uri The Uri of the input.
 * @return The index of the first extracted sample written to the given {@code trackOutput} after
 *     the seek is completed, or {@link C#INDEX_UNSET} if the seek is completed without any
 *     extracted sample.
 */
public static int seekToTimeUs(Extractor extractor, SeekMap seekMap, long seekTimeUs, DataSource dataSource, FakeTrackOutput trackOutput, Uri uri) throws IOException {
    int numSampleBeforeSeek = trackOutput.getSampleCount();
    SeekMap.SeekPoints seekPoints = seekMap.getSeekPoints(seekTimeUs);
    long initialSeekLoadPosition = seekPoints.first.position;
    extractor.seek(initialSeekLoadPosition, seekTimeUs);
    PositionHolder positionHolder = new PositionHolder();
    positionHolder.position = C.POSITION_UNSET;
    ExtractorInput extractorInput = TestUtil.getExtractorInputFromPosition(dataSource, initialSeekLoadPosition, uri);
    int extractorReadResult = Extractor.RESULT_CONTINUE;
    while (true) {
        try {
            // Keep reading until we can read at least one sample after seek
            while (extractorReadResult == Extractor.RESULT_CONTINUE && trackOutput.getSampleCount() == numSampleBeforeSeek) {
                extractorReadResult = extractor.read(extractorInput, positionHolder);
            }
        } finally {
            DataSourceUtil.closeQuietly(dataSource);
        }
        if (extractorReadResult == Extractor.RESULT_SEEK) {
            extractorInput = TestUtil.getExtractorInputFromPosition(dataSource, positionHolder.position, uri);
            extractorReadResult = Extractor.RESULT_CONTINUE;
        } else if (extractorReadResult == Extractor.RESULT_END_OF_INPUT && trackOutput.getSampleCount() == numSampleBeforeSeek) {
            return C.INDEX_UNSET;
        } else if (trackOutput.getSampleCount() > numSampleBeforeSeek) {
            // First index after seek = num sample before seek.
            return numSampleBeforeSeek;
        }
    }
}
Also used : ExtractorInput(com.google.android.exoplayer2.extractor.ExtractorInput) DefaultExtractorInput(com.google.android.exoplayer2.extractor.DefaultExtractorInput) PositionHolder(com.google.android.exoplayer2.extractor.PositionHolder) SeekMap(com.google.android.exoplayer2.extractor.SeekMap)

Example 18 with C

use of com.google.android.exoplayer2.C in project Slide by ccrama.

the class Reddit method setDefaultErrorHandler.

public static void setDefaultErrorHandler(Context base) {
    // START code adapted from https://github.com/QuantumBadger/RedReader/
    final Thread.UncaughtExceptionHandler androidHandler = Thread.getDefaultUncaughtExceptionHandler();
    final WeakReference<Context> cont = new WeakReference<>(base);
    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

        public void uncaughtException(Thread thread, Throwable t) {
            if (cont.get() != null) {
                final Context c = cont.get();
                Writer writer = new StringWriter();
                PrintWriter printWriter = new PrintWriter(writer);
                t.printStackTrace(printWriter);
                String stacktrace = writer.toString().replace(";", ",");
                if (stacktrace.contains("UnknownHostException") || stacktrace.contains("SocketTimeoutException") || stacktrace.contains("ConnectException")) {
                    // is offline
                    final Handler mHandler = new Handler(Looper.getMainLooper());
                    mHandler.post(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                new AlertDialog.Builder(c).setTitle(R.string.err_title).setMessage(R.string.err_connection_failed_msg).setNegativeButton(R.string.btn_close, (dialog, which) -> {
                                    if (!(c instanceof MainActivity)) {
                                        ((Activity) c).finish();
                                    }
                                }).setPositiveButton(R.string.btn_offline, (dialog, which) -> {
                                    Reddit.appRestart.edit().putBoolean("forceoffline", true).apply();
                                    Reddit.forceRestart(c, false);
                                }).show();
                            } catch (Exception ignored) {
                            }
                        }
                    });
                } else if (stacktrace.contains("403 Forbidden") || stacktrace.contains("401 Unauthorized")) {
                    // Un-authenticated
                    final Handler mHandler = new Handler(Looper.getMainLooper());
                    mHandler.post(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                new AlertDialog.Builder(c).setTitle(R.string.err_title).setMessage(R.string.err_refused_request_msg).setNegativeButton("No", (dialog, which) -> {
                                    if (!(c instanceof MainActivity)) {
                                        ((Activity) c).finish();
                                    }
                                }).setPositiveButton("Yes", (dialog, which) -> authentication.updateToken(c)).show();
                            } catch (Exception ignored) {
                            }
                        }
                    });
                } else if (stacktrace.contains("404 Not Found") || stacktrace.contains("400 Bad Request")) {
                    final Handler mHandler = new Handler(Looper.getMainLooper());
                    mHandler.post(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                new AlertDialog.Builder(c).setTitle(R.string.err_title).setMessage(R.string.err_could_not_find_content_msg).setNegativeButton("Close", (dialog, which) -> {
                                    if (!(c instanceof MainActivity)) {
                                        ((Activity) c).finish();
                                    }
                                }).show();
                            } catch (Exception ignored) {
                            }
                        }
                    });
                } else if (t instanceof NetworkException) {
                    Toast.makeText(c, "Error " + ((NetworkException) t).getResponse().getStatusMessage() + ": " + (t).getMessage(), Toast.LENGTH_LONG).show();
                } else if (t instanceof NullPointerException && t.getMessage().contains("Attempt to invoke virtual method 'android.content.Context android.view.ViewGroup.getContext()' on a null object reference")) {
                    t.printStackTrace();
                } else if (t instanceof WindowManager.BadTokenException) {
                    t.printStackTrace();
                } else if (t instanceof IllegalArgumentException && t.getMessage().contains("pointerIndex out of range")) {
                    t.printStackTrace();
                } else {
                    appRestart.edit().putString("startScreen", "a").apply();
                    try {
                        SharedPreferences prefs = c.getSharedPreferences("STACKTRACE", Context.MODE_PRIVATE);
                        prefs.edit().putString("stacktrace", stacktrace).apply();
                    } catch (Throwable ignored) {
                    }
                    androidHandler.uncaughtException(thread, t);
                }
            } else {
                androidHandler.uncaughtException(thread, t);
            }
        }
    });
// END adaptation
}
Also used : AlertDialog(androidx.appcompat.app.AlertDialog) MultiDexApplication(androidx.multidex.MultiDexApplication) Bundle(android.os.Bundle) PackageManager(android.content.pm.PackageManager) MainActivity(me.ccrama.redditslide.Activities.MainActivity) Uri(android.net.Uri) WindowManager(android.view.WindowManager) NotificationChannelCompat(androidx.core.app.NotificationChannelCompat) DatabaseProvider(com.google.android.exoplayer2.database.DatabaseProvider) InetAddress(java.net.InetAddress) IabHelper(me.ccrama.redditslide.util.billing.IabHelper) UiModeManager(android.app.UiModeManager) ImageLoaderUtils(me.ccrama.redditslide.util.ImageLoaderUtils) Locale(java.util.Locale) Handler(android.os.Handler) Looper(android.os.Looper) NotificationManagerCompat(androidx.core.app.NotificationManagerCompat) AutoCacheScheduler(me.ccrama.redditslide.Autocache.AutoCacheScheduler) Cache(com.google.android.exoplayer2.upstream.cache.Cache) SimpleCache(com.google.android.exoplayer2.upstream.cache.SimpleCache) ContextCompat(androidx.core.content.ContextCompat) Triple(org.apache.commons.lang3.tuple.Triple) TargetApi(android.annotation.TargetApi) Log(android.util.Log) PrintWriter(java.io.PrintWriter) AsyncTask(android.os.AsyncTask) NotificationJobScheduler(me.ccrama.redditslide.Notifications.NotificationJobScheduler) Palette(me.ccrama.redditslide.Visuals.Palette) NotificationPiggyback(me.ccrama.redditslide.Notifications.NotificationPiggyback) GifCache(me.ccrama.redditslide.util.GifCache) List(java.util.List) NetworkUtil(me.ccrama.redditslide.util.NetworkUtil) LeastRecentlyUsedCacheEvictor(com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor) Application(android.app.Application) SortingUtil(me.ccrama.redditslide.util.SortingUtil) Writer(java.io.Writer) ActivityManager(android.app.ActivityManager) Context(android.content.Context) AlertDialog(androidx.appcompat.app.AlertDialog) ResourcesCompat(androidx.core.content.res.ResourcesCompat) AdBlocker(me.ccrama.redditslide.util.AdBlocker) Environment(android.os.Environment) AlbumUtils(me.ccrama.redditslide.ImgurAlbum.AlbumUtils) ExoDatabaseProvider(com.google.android.exoplayer2.database.ExoDatabaseProvider) TumblrUtils(me.ccrama.redditslide.Tumblr.TumblrUtils) Intent(android.content.Intent) HashMap(java.util.HashMap) LogUtil(me.ccrama.redditslide.util.LogUtil) PackageInfo(android.content.pm.PackageInfo) ProcessPhoenix(com.jakewharton.processphoenix.ProcessPhoenix) ArrayList(java.util.ArrayList) Calendar(java.util.Calendar) IabResult(me.ccrama.redditslide.util.billing.IabResult) Toast(android.widget.Toast) Build(android.os.Build) WeakReference(java.lang.ref.WeakReference) UpgradeUtil(me.ccrama.redditslide.util.UpgradeUtil) StringWriter(java.io.StringWriter) KVStore(com.lusfold.androidkeyvaluestore.KVStore) StringEscapeUtils(org.apache.commons.text.StringEscapeUtils) ImageLoader(com.nostra13.universalimageloader.core.ImageLoader) Inet4Address(java.net.Inet4Address) UnknownHostException(java.net.UnknownHostException) Dns(okhttp3.Dns) File(java.io.File) ResolveInfo(android.content.pm.ResolveInfo) CompatUtil(me.ccrama.redditslide.util.CompatUtil) OkHttpClient(okhttp3.OkHttpClient) SharedPreferences(android.content.SharedPreferences) Configuration(android.content.res.Configuration) Activity(android.app.Activity) NetworkException(net.dean.jraw.http.NetworkException) MainActivity(me.ccrama.redditslide.Activities.MainActivity) Activity(android.app.Activity) MainActivity(me.ccrama.redditslide.Activities.MainActivity) StringWriter(java.io.StringWriter) WeakReference(java.lang.ref.WeakReference) NetworkException(net.dean.jraw.http.NetworkException) PrintWriter(java.io.PrintWriter) Context(android.content.Context) SharedPreferences(android.content.SharedPreferences) Handler(android.os.Handler) UnknownHostException(java.net.UnknownHostException) NetworkException(net.dean.jraw.http.NetworkException) PrintWriter(java.io.PrintWriter) Writer(java.io.Writer) StringWriter(java.io.StringWriter)

Example 19 with C

use of com.google.android.exoplayer2.C in project ExoPlayer by google.

the class MappingTrackSelector method maybeConfigureRenderersForTunneling.

/**
   * Determines whether tunneling should be enabled, replacing {@link RendererConfiguration}s in
   * {@code rendererConfigurations} with configurations that enable tunneling on the appropriate
   * renderers if so.
   *
   * @param rendererCapabilities The {@link RendererCapabilities} of the renderers for which
   *     {@link TrackSelection}s are to be generated.
   * @param rendererTrackGroupArrays An array of {@link TrackGroupArray}s where each entry
   *     corresponds to the renderer of equal index in {@code renderers}.
   * @param rendererFormatSupports Maps every available track to a specific level of support as
   *     defined by the renderer {@code FORMAT_*} constants.
   * @param rendererConfigurations The renderer configurations. Configurations may be replaced with
   *     ones that enable tunneling as a result of this call.
   * @param trackSelections The renderer track selections.
   * @param tunnelingAudioSessionId The audio session id to use when tunneling, or
   *     {@link C#AUDIO_SESSION_ID_UNSET} if tunneling should not be enabled.
   */
private static void maybeConfigureRenderersForTunneling(RendererCapabilities[] rendererCapabilities, TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports, RendererConfiguration[] rendererConfigurations, TrackSelection[] trackSelections, int tunnelingAudioSessionId) {
    if (tunnelingAudioSessionId == C.AUDIO_SESSION_ID_UNSET) {
        return;
    }
    // Check whether we can enable tunneling. To enable tunneling we require exactly one audio and
    // one video renderer to support tunneling and have a selection.
    int tunnelingAudioRendererIndex = -1;
    int tunnelingVideoRendererIndex = -1;
    boolean enableTunneling = true;
    for (int i = 0; i < rendererCapabilities.length; i++) {
        int rendererType = rendererCapabilities[i].getTrackType();
        TrackSelection trackSelection = trackSelections[i];
        if ((rendererType == C.TRACK_TYPE_AUDIO || rendererType == C.TRACK_TYPE_VIDEO) && trackSelection != null) {
            if (rendererSupportsTunneling(rendererFormatSupports[i], rendererTrackGroupArrays[i], trackSelection)) {
                if (rendererType == C.TRACK_TYPE_AUDIO) {
                    if (tunnelingAudioRendererIndex != -1) {
                        enableTunneling = false;
                        break;
                    } else {
                        tunnelingAudioRendererIndex = i;
                    }
                } else {
                    if (tunnelingVideoRendererIndex != -1) {
                        enableTunneling = false;
                        break;
                    } else {
                        tunnelingVideoRendererIndex = i;
                    }
                }
            }
        }
    }
    enableTunneling &= tunnelingAudioRendererIndex != -1 && tunnelingVideoRendererIndex != -1;
    if (enableTunneling) {
        RendererConfiguration tunnelingRendererConfiguration = new RendererConfiguration(tunnelingAudioSessionId);
        rendererConfigurations[tunnelingAudioRendererIndex] = tunnelingRendererConfiguration;
        rendererConfigurations[tunnelingVideoRendererIndex] = tunnelingRendererConfiguration;
    }
}
Also used : RendererConfiguration(com.google.android.exoplayer2.RendererConfiguration)

Example 20 with C

use of com.google.android.exoplayer2.C in project ExoPlayer by google.

the class EventSampleStreamTest method readDataOutOfBoundReturnEndOfStreamAfterFormatForNonDynamicEventSampleStream.

/**
 * Tests that a non-dynamic {@link EventSampleStream} will return a buffer with {@link
 * C#BUFFER_FLAG_END_OF_STREAM} when trying to read sample out-of-bound.
 */
@Test
public void readDataOutOfBoundReturnEndOfStreamAfterFormatForNonDynamicEventSampleStream() {
    EventStream eventStream = new EventStream(SCHEME_ID, VALUE, TIME_SCALE, new long[0], new EventMessage[0]);
    EventSampleStream sampleStream = new EventSampleStream(eventStream, FORMAT, false);
    // first read - read format
    readData(sampleStream);
    int result = readData(sampleStream);
    assertThat(result).isEqualTo(C.RESULT_BUFFER_READ);
    assertThat(inputBuffer.isEndOfStream()).isTrue();
}
Also used : EventStream(com.google.android.exoplayer2.source.dash.manifest.EventStream) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)14 BaseUrl (com.google.android.exoplayer2.source.dash.manifest.BaseUrl)6 Format (com.google.android.exoplayer2.Format)5 SeekPoint (com.google.android.exoplayer2.extractor.SeekPoint)5 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)4 IOException (java.io.IOException)4 Nullable (androidx.annotation.Nullable)3 RendererCapabilities (com.google.android.exoplayer2.RendererCapabilities)3 HashMap (java.util.HashMap)3 Metadata (com.google.android.exoplayer2.metadata.Metadata)2 EventStream (com.google.android.exoplayer2.source.dash.manifest.EventStream)2 InterruptedIOException (java.io.InterruptedIOException)2 TargetApi (android.annotation.TargetApi)1 Activity (android.app.Activity)1 ActivityManager (android.app.ActivityManager)1 Application (android.app.Application)1 UiModeManager (android.app.UiModeManager)1 Context (android.content.Context)1 Intent (android.content.Intent)1 SharedPreferences (android.content.SharedPreferences)1