Skip to content

Conversation

Isira-Seneviratne
Copy link
Member

@Isira-Seneviratne Isira-Seneviratne commented Sep 12, 2025

  • I carefully read the contribution guidelines and agree to them.
  • I have tested the API against NewPipe.
  • I agree to create a pull request for NewPipe as soon as possible to make it compatible with the changed API.

  • Update the DateWrapper class to store an Instant, and remove the deprecated methods.
  • [YouTube] Improve the upload date parsing so that non-approximate dates can be returned.
  • [SoundCloud] Return the original instant string in the stream extractor.

Copy link
Contributor

@TobiGr TobiGr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

Comment on lines 177 to 188
final String dateStr = playerMicroFormatRenderer.getString("uploadDate",
playerMicroFormatRenderer.getString("publishDate", ""));
if (!dateStr.isEmpty()) {
return dateStr;
}

final JsonObject liveDetails = playerMicroFormatRenderer.getObject(
"liveBroadcastDetails");
if (!liveDetails.getString("endTimestamp", "").isEmpty()) {
// an ended live stream
return liveDetails.getString("endTimestamp");
} else if (!liveDetails.getString("startTimestamp", "").isEmpty()) {
// a running live stream
return liveDetails.getString("startTimestamp");
final var liveDetails = playerMicroFormatRenderer.getObject("liveBroadcastDetails");
final String timestamp = liveDetails.getString("endTimestamp", // an ended live stream
liveDetails.getString("startTimestamp", "")); // a running live stream

if (!timestamp.isEmpty()) {
return timestamp;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes it harder to understand what's going on. I'd prefer to keep it readable and revert this change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the code below line 180 as a whole could be removed. I checked how the date is being extracted, and it's always taken from uploadDate or publishDate.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YouTube might return different layouts in different cases, so it's better to keep all cases

@TobiGr
Copy link
Contributor

TobiGr commented Sep 17, 2025

Please list all the breaking changes in the PR description so they can be copied to the release notes.

@TobiGr
Copy link
Contributor

TobiGr commented Sep 17, 2025

The tests are now dependent on the runner's time zone, which is not good. While the automated tests pass (server is set to UTC), tests on my computer fail:

results

YoutubeStreamExtractorControversialTest > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2010-09-09T15:40:44> but was: <2010-09-09T17:40:44>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorDefaultTest$DescriptionTestPewdiepie > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2019-08-24T15:39:57> but was: <2019-08-24T17:39:57>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorDefaultTest$DescriptionTestUnboxing > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2018-06-19T19:41:34> but was: <2018-06-19T21:41:34>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorDefaultTest$NoVisualMetadataVideoTest > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2017-05-16T14:50:53> but was: <2017-05-16T16:50:53>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorDefaultTest$PublicBroadcasterTest > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2023-07-07T15:30:08> but was: <2023-07-07T17:30:08>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorDefaultTest$RatingsDisabledTest > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2023-01-13T21:53:57> but was: <2023-01-13T22:53:57>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorDefaultTest$StreamSegmentsTestMaiLab > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2020-11-19T05:30:01> but was: <2020-11-19T06:30:01>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorDefaultTest$StreamSegmentsTestMaiLab > testName() SKIPPED

YoutubeStreamExtractorDefaultTest$StreamSegmentsTestMaiLab > testTags() SKIPPED

YoutubeStreamExtractorDefaultTest$StreamSegmentsTestTagesschau > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2021-03-17T19:56:59> but was: <2021-03-17T20:56:59>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorLivestreamTest > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2022-07-12T12:12:29> but was: <2022-07-12T14:12:29>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorRelatedMixTest > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2015-07-09T16:34:35> but was: <2015-07-09T18:34:35>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)

YoutubeStreamExtractorUnlistedTest > testUploadDate() FAILED
    org.opentest4j.AssertionFailedError: expected: <2017-09-22T12:15:21> but was: <2017-09-22T14:15:21>
        at app//org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest.testUploadDate(DefaultStreamExtractorTest.java:206)
        at java.base@17.0.16/java.lang.reflect.Method.invoke(Method.java:569)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base@17.0.16/java.util.ArrayList.forEach(ArrayList.java:1511)


@Stypox
Copy link
Member

Stypox commented Sep 17, 2025

Mmmh, what's the advantage of using Instant instead of OffsetDateTime? I see this PR does many changes but I don't see clear advantages. I mean, sure, some code is shorter, but the longer code we had before worked just fine, or was there some limitation I am not getting?

@Isira-Seneviratne
Copy link
Member Author

Mmmh, what's the advantage of using Instant instead of OffsetDateTime? I see this PR does many changes but I don't see clear advantages. I mean, sure, some code is shorter, but the longer code we had before worked just fine, or was there some limitation I am not getting?

Instant represents a single point of time in the UTC time zone, while OffsetDateTime stores a zone offset. As such, I felt that storing an Instant would be better as it avoids having to convert between different time zones in order to obtain it, and a local date/time value can be obtained via their factory methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants