Search in sources :

Example 21 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.

the class DashManifestParserTest method parseEssentialAndSupplementalProperties.

@Test
public void parseEssentialAndSupplementalProperties() throws IOException {
    DashManifestParser parser = new DashManifestParser();
    DashManifest manifest = parser.parse(Uri.parse("https://example.com/test.mpd"), TestUtil.getInputStream(ApplicationProvider.getApplicationContext(), SAMPLE_MPD_ESSENTIAL_SUPPLEMENTAL_PROPERTIES));
    // Verify test setup.
    assertThat(manifest.getPeriodCount()).isEqualTo(1);
    assertThat(manifest.getPeriod(0).adaptationSets).hasSize(1);
    AdaptationSet adaptationSet = manifest.getPeriod(0).adaptationSets.get(0);
    assertThat(adaptationSet.representations).hasSize(2);
    Representation representation0 = adaptationSet.representations.get(0);
    Representation representation1 = adaptationSet.representations.get(1);
    assertThat(representation0).isInstanceOf(SingleSegmentRepresentation.class);
    assertThat(representation1).isInstanceOf(MultiSegmentRepresentation.class);
    // Verify parsed properties.
    assertThat(adaptationSet.essentialProperties).hasSize(1);
    assertThat(adaptationSet.essentialProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(adaptationSet.essentialProperties.get(0).value).isEqualTo("adaptationEssential");
    assertThat(adaptationSet.supplementalProperties).hasSize(1);
    assertThat(adaptationSet.supplementalProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(adaptationSet.supplementalProperties.get(0).value).isEqualTo("adaptationSupplemental");
    assertThat(representation0.essentialProperties).hasSize(2);
    assertThat(representation0.essentialProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(representation0.essentialProperties.get(0).value).isEqualTo("adaptationEssential");
    assertThat(representation0.essentialProperties.get(1).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(representation0.essentialProperties.get(1).value).isEqualTo("representationEssential");
    assertThat(representation0.supplementalProperties).hasSize(2);
    assertThat(representation0.supplementalProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(representation0.supplementalProperties.get(0).value).isEqualTo("adaptationSupplemental");
    assertThat(representation0.supplementalProperties.get(1).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(representation0.supplementalProperties.get(1).value).isEqualTo("representationSupplemental");
    assertThat(representation1.essentialProperties).hasSize(2);
    assertThat(representation0.essentialProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(representation0.essentialProperties.get(0).value).isEqualTo("adaptationEssential");
    assertThat(representation1.essentialProperties.get(1).schemeIdUri).isEqualTo("urn:mpeg:dash:essential-scheme:2050");
    assertThat(representation1.essentialProperties.get(1).value).isEqualTo("representationEssential");
    assertThat(representation1.supplementalProperties).hasSize(2);
    assertThat(representation0.supplementalProperties.get(0).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(representation0.supplementalProperties.get(0).value).isEqualTo("adaptationSupplemental");
    assertThat(representation1.supplementalProperties.get(1).schemeIdUri).isEqualTo("urn:mpeg:dash:supplemental-scheme:2050");
    assertThat(representation1.supplementalProperties.get(1).value).isEqualTo("representationSupplemental");
}
Also used : SingleSegmentRepresentation(com.google.android.exoplayer2.source.dash.manifest.Representation.SingleSegmentRepresentation) MultiSegmentRepresentation(com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation) Test(org.junit.Test)

Example 22 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.

the class AvcConfig method parse.

/**
 * Parses AVC configuration data.
 *
 * @param data A {@link ParsableByteArray}, whose position is set to the start of the AVC
 *     configuration data to parse.
 * @return A parsed representation of the AVC configuration data.
 * @throws ParserException If an error occurred parsing the data.
 */
public static AvcConfig parse(ParsableByteArray data) throws ParserException {
    try {
        // Skip to the AVCDecoderConfigurationRecord (defined in 14496-15)
        data.skipBytes(4);
        int nalUnitLengthFieldLength = (data.readUnsignedByte() & 0x3) + 1;
        if (nalUnitLengthFieldLength == 3) {
            throw new IllegalStateException();
        }
        List<byte[]> initializationData = new ArrayList<>();
        int numSequenceParameterSets = data.readUnsignedByte() & 0x1F;
        for (int j = 0; j < numSequenceParameterSets; j++) {
            initializationData.add(buildNalUnitForChild(data));
        }
        int numPictureParameterSets = data.readUnsignedByte();
        for (int j = 0; j < numPictureParameterSets; j++) {
            initializationData.add(buildNalUnitForChild(data));
        }
        int width = Format.NO_VALUE;
        int height = Format.NO_VALUE;
        float pixelWidthHeightRatio = 1;
        @Nullable String codecs = null;
        if (numSequenceParameterSets > 0) {
            byte[] sps = initializationData.get(0);
            SpsData spsData = NalUnitUtil.parseSpsNalUnit(initializationData.get(0), nalUnitLengthFieldLength, sps.length);
            width = spsData.width;
            height = spsData.height;
            pixelWidthHeightRatio = spsData.pixelWidthHeightRatio;
            codecs = CodecSpecificDataUtil.buildAvcCodecString(spsData.profileIdc, spsData.constraintsFlagsAndReservedZero2Bits, spsData.levelIdc);
        }
        return new AvcConfig(initializationData, nalUnitLengthFieldLength, width, height, pixelWidthHeightRatio, codecs);
    } catch (ArrayIndexOutOfBoundsException e) {
        throw ParserException.createForMalformedContainer("Error parsing AVC config", e);
    }
}
Also used : ArrayList(java.util.ArrayList) SpsData(com.google.android.exoplayer2.util.NalUnitUtil.SpsData) Nullable(androidx.annotation.Nullable)

Example 23 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project Slide by ccrama.

the class GifUtils method cacheSaveGif.

/**
 * Temporarily cache or permanently save a GIF
 *
 * @param uri       URL of the GIF
 * @param a
 * @param subreddit Subreddit for saving in sub-specific folders
 * @param save      Whether to permanently save the GIF of just temporarily cache it
 */
public static void cacheSaveGif(Uri uri, Activity a, String subreddit, String submissionTitle, boolean save) {
    if (save) {
        try {
            Toast.makeText(a, a.getString(R.string.mediaview_notif_title), Toast.LENGTH_SHORT).show();
        } catch (Exception ignored) {
        }
    }
    if (Reddit.appRestart.getString("imagelocation", "").isEmpty()) {
        showFirstDialog(a);
    } else if (!new File(Reddit.appRestart.getString("imagelocation", "")).exists()) {
        showErrorDialog(a);
    } else {
        new AsyncTask<Void, Integer, Boolean>() {

            File outFile;

            NotificationManager notifMgr = ContextCompat.getSystemService(a, NotificationManager.class);

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                if (save) {
                    Notification notif = new NotificationCompat.Builder(a, Reddit.CHANNEL_IMG).setContentTitle(a.getString(R.string.mediaview_saving, uri.toString().replace("/DASHPlaylist.mpd", ""))).setSmallIcon(R.drawable.ic_download).setProgress(0, 0, true).setOngoing(true).build();
                    notifMgr.notify(1, notif);
                }
            }

            @Override
            protected Boolean doInBackground(Void... voids) {
                String folderPath = Reddit.appRestart.getString("imagelocation", "");
                String subFolderPath = "";
                if (SettingValues.imageSubfolders && !subreddit.isEmpty()) {
                    subFolderPath = File.separator + subreddit;
                }
                String extension = ".mp4";
                outFile = FileUtil.getValidFile(folderPath, subFolderPath, submissionTitle, "", extension);
                OutputStream out = null;
                InputStream in = null;
                try {
                    DataSource.Factory downloader = new OkHttpDataSource.Factory(Reddit.client).setUserAgent(a.getString(R.string.app_name));
                    DataSource.Factory cacheDataSourceFactory = new CacheDataSource.Factory().setCache(Reddit.videoCache).setUpstreamDataSourceFactory(downloader);
                    if (uri.getLastPathSegment().endsWith("DASHPlaylist.mpd")) {
                        InputStream dashManifestStream = new DataSourceInputStream(cacheDataSourceFactory.createDataSource(), new DataSpec(uri));
                        DashManifest dashManifest = new DashManifestParser().parse(uri, dashManifestStream);
                        dashManifestStream.close();
                        Uri audioUri = null;
                        Uri videoUri = null;
                        for (int i = 0; i < dashManifest.getPeriodCount(); i++) {
                            for (AdaptationSet as : dashManifest.getPeriod(i).adaptationSets) {
                                boolean isAudio = false;
                                int bitrate = 0;
                                String hqUri = null;
                                for (Representation r : as.representations) {
                                    if (r.format.bitrate > bitrate) {
                                        bitrate = r.format.bitrate;
                                        hqUri = r.baseUrl;
                                    }
                                    if (MimeTypes.isAudio(r.format.sampleMimeType)) {
                                        isAudio = true;
                                    }
                                }
                                if (isAudio) {
                                    audioUri = Uri.parse(hqUri);
                                } else {
                                    videoUri = Uri.parse(hqUri);
                                }
                            }
                        }
                        if (audioUri != null) {
                            LogUtil.v("Downloading DASH audio from: " + audioUri);
                            DataSourceInputStream audioInputStream = new DataSourceInputStream(cacheDataSourceFactory.createDataSource(), new DataSpec(audioUri));
                            if (save) {
                                FileUtils.copyInputStreamToFile(audioInputStream, new File(a.getCacheDir().getAbsolutePath(), "audio.mp4"));
                            } else {
                                IOUtils.copy(audioInputStream, NullOutputStream.NULL_OUTPUT_STREAM);
                            }
                            audioInputStream.close();
                        }
                        if (videoUri != null) {
                            LogUtil.v("Downloading DASH video from: " + videoUri);
                            DataSourceInputStream videoInputStream = new DataSourceInputStream(cacheDataSourceFactory.createDataSource(), new DataSpec(videoUri));
                            if (save) {
                                FileUtils.copyInputStreamToFile(videoInputStream, new File(a.getCacheDir().getAbsolutePath(), "video.mp4"));
                            } else {
                                IOUtils.copy(videoInputStream, NullOutputStream.NULL_OUTPUT_STREAM);
                            }
                            videoInputStream.close();
                        }
                        if (!save) {
                            return true;
                        } else if (audioUri != null && videoUri != null) {
                            if (mux(new File(a.getCacheDir().getAbsolutePath(), "video.mp4").getAbsolutePath(), new File(a.getCacheDir().getAbsolutePath(), "audio.mp4").getAbsolutePath(), new File(a.getCacheDir().getAbsolutePath(), "muxed.mp4").getAbsolutePath())) {
                                in = new FileInputStream(new File(a.getCacheDir().getAbsolutePath(), "muxed.mp4"));
                            } else {
                                throw new IOException("Muxing failed!");
                            }
                        } else {
                            in = new FileInputStream(new File(a.getCacheDir().getAbsolutePath(), "video.mp4"));
                        }
                    } else {
                        in = new DataSourceInputStream(cacheDataSourceFactory.createDataSource(), new DataSpec(uri));
                    }
                    out = save ? new FileOutputStream(outFile) : NullOutputStream.NULL_OUTPUT_STREAM;
                    IOUtils.copy(in, out);
                    out.close();
                } catch (Exception e) {
                    e.printStackTrace();
                    LogUtil.e("Error saving GIF called with: " + "from = [" + uri + "], in = [" + in + "]");
                    return false;
                } finally {
                    try {
                        if (out != null) {
                            out.close();
                        }
                        if (in != null) {
                            in.close();
                        }
                    } catch (IOException e) {
                        LogUtil.e("Error closing GIF called with: " + "from = [" + uri + "], out = [" + out + "]");
                        return false;
                    }
                }
                return true;
            }

            @Override
            protected void onPostExecute(Boolean success) {
                super.onPostExecute(success);
                if (save) {
                    notifMgr.cancel(1);
                    if (success) {
                        doNotifGif(outFile, a);
                    } else {
                        showErrorDialog(a);
                    }
                }
            }
        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }
}
Also used : OkHttpDataSource(com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) NullOutputStream(org.apache.commons.io.output.NullOutputStream) DashManifest(com.google.android.exoplayer2.source.dash.manifest.DashManifest) Uri(android.net.Uri) Notification(android.app.Notification) DashManifestParser(com.google.android.exoplayer2.source.dash.manifest.DashManifestParser) NotificationCompat(androidx.core.app.NotificationCompat) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) DataSourceInputStream(com.google.android.exoplayer2.upstream.DataSourceInputStream) NotificationManager(android.app.NotificationManager) DataSourceInputStream(com.google.android.exoplayer2.upstream.DataSourceInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) AsyncTask(android.os.AsyncTask) Representation(com.google.android.exoplayer2.source.dash.manifest.Representation) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) BufferOverflowException(java.nio.BufferOverflowException) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) DataSource(com.google.android.exoplayer2.upstream.DataSource) CacheDataSource(com.google.android.exoplayer2.upstream.cache.CacheDataSource) OkHttpDataSource(com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource) FileOutputStream(java.io.FileOutputStream) AdaptationSet(com.google.android.exoplayer2.source.dash.manifest.AdaptationSet) File(java.io.File)

Example 24 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.

the class DashManifest method copyAdaptationSets.

private static ArrayList<AdaptationSet> copyAdaptationSets(List<AdaptationSet> adaptationSets, LinkedList<StreamKey> keys) {
    StreamKey key = keys.poll();
    int periodIndex = key.periodIndex;
    ArrayList<AdaptationSet> copyAdaptationSets = new ArrayList<>();
    do {
        int adaptationSetIndex = key.groupIndex;
        AdaptationSet adaptationSet = adaptationSets.get(adaptationSetIndex);
        List<Representation> representations = adaptationSet.representations;
        ArrayList<Representation> copyRepresentations = new ArrayList<>();
        do {
            Representation representation = representations.get(key.streamIndex);
            copyRepresentations.add(representation);
            key = keys.poll();
        } while (key.periodIndex == periodIndex && key.groupIndex == adaptationSetIndex);
        copyAdaptationSets.add(new AdaptationSet(adaptationSet.id, adaptationSet.type, copyRepresentations, adaptationSet.accessibilityDescriptors, adaptationSet.essentialProperties, adaptationSet.supplementalProperties));
    } while (key.periodIndex == periodIndex);
    // Add back the last key which doesn't belong to the period being processed
    keys.addFirst(key);
    return copyAdaptationSets;
}
Also used : ArrayList(java.util.ArrayList) StreamKey(com.google.android.exoplayer2.offline.StreamKey)

Example 25 with Representation

use of com.google.android.exoplayer2.source.dash.manifest.Representation in project ExoPlayer by google.

the class DashUtilTest method resolveCacheKey_representationCacheKeyIsNull_resolvesRangedUriWithFirstBaseUrl.

@Test
public void resolveCacheKey_representationCacheKeyIsNull_resolvesRangedUriWithFirstBaseUrl() {
    ImmutableList<BaseUrl> baseUrls = ImmutableList.of(new BaseUrl("http://www.google.com"), new BaseUrl("http://www.foo.com"));
    Representation.SingleSegmentRepresentation representation = new Representation.SingleSegmentRepresentation(/* revisionId= */
    1L, new Format.Builder().build(), baseUrls, new SingleSegmentBase(), /* inbandEventStreams= */
    null, /* essentialProperties= */
    ImmutableList.of(), /* supplementalProperties= */
    ImmutableList.of(), /* cacheKey= */
    null, /* contentLength= */
    1);
    RangedUri rangedUri = new RangedUri("path/to/resource", /* start= */
    0, /* length= */
    1);
    String cacheKey = DashUtil.resolveCacheKey(representation, rangedUri);
    assertThat(cacheKey).isEqualTo("http://www.google.com/path/to/resource");
}
Also used : SingleSegmentBase(com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase) RangedUri(com.google.android.exoplayer2.source.dash.manifest.RangedUri) Representation(com.google.android.exoplayer2.source.dash.manifest.Representation) BaseUrl(com.google.android.exoplayer2.source.dash.manifest.BaseUrl) Test(org.junit.Test)

Aggregations

Representation (com.google.android.exoplayer2.source.dash.manifest.Representation)18 Nullable (androidx.annotation.Nullable)12 RangedUri (com.google.android.exoplayer2.source.dash.manifest.RangedUri)10 Format (com.google.android.exoplayer2.Format)9 AdaptationSet (com.google.android.exoplayer2.source.dash.manifest.AdaptationSet)7 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)6 ArrayList (java.util.ArrayList)6 SingleSegmentBase (com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase)5 Test (org.junit.Test)5 SchemeData (com.google.android.exoplayer2.drm.DrmInitData.SchemeData)4 StreamKey (com.google.android.exoplayer2.offline.StreamKey)3 BehindLiveWindowException (com.google.android.exoplayer2.source.BehindLiveWindowException)3 ContainerMediaChunk (com.google.android.exoplayer2.source.chunk.ContainerMediaChunk)3 InitializationChunk (com.google.android.exoplayer2.source.chunk.InitializationChunk)3 SingleSampleMediaChunk (com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk)3 MultiSegmentRepresentation (com.google.android.exoplayer2.source.dash.manifest.Representation.MultiSegmentRepresentation)3 IOException (java.io.IOException)3 DrmInitData (com.google.android.exoplayer2.drm.DrmInitData)2 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)2 DashSegmentIndex (com.google.android.exoplayer2.source.dash.DashSegmentIndex)2