datawhores / OF-Scraper

A completely revamped and redesigned fork, reimagined from scratch based on the original onlyfans-scraper
MIT License
668 stars 56 forks source link

Media files now use "full" instead of "source" quality #452

Closed sixinchfootlong closed 1 month ago

sixinchfootlong commented 1 month ago

The API responses have recently(?) changed. The media files structure now uses "full" for the max quality instead of "source". Any downloads that would have used "source" quality no longer work because the key has been renamed.

Example:

{
    "id": 1234567890,
    "type": "photo",
    "convertedToVideo": false,
    "canView": true,
    "hasError": false,
    "createdAt": null,
    "isReady": true,
    "files": {
        "full": {
            "url": "https:\/\/cdn2.onlyfans.com\/files\/...",
            "width": 1170,
            "height": 625,
            "size": 0,
            "sources": []
        },
        "thumb": {
            "url": "https:\/\/cdn2.onlyfans.com\/files\/...",
            "width": 300,
            "height": 300,
            "size": 0
        },
        "preview": {
            "url": "https:\/\/cdn2.onlyfans.com\/files\/...",
            "width": 960,
            "height": 513,
            "size": 0
        },
        "squarePreview": {
            "url": "https:\/\/cdn2.onlyfans.com\/files\/...",
            "width": 960,
            "height": 960,
            "size": 0
        }
    },
    "duration": 0,
    "hasCustomPreview": false,
    "videoSources": {
        "720": null,
        "240": null
    }
},

Note that files.source no longer exists.

datawhores commented 1 month ago

Did you update Is this related to --quality arg

or quality placeholder

sixinchfootlong commented 1 month ago

Neither. I'm letting you know that the OnlyFans API response structure has changed.

The list of media in a post/message/etc no longer has a "source" key. The "files" attribute also no longer has a "source" entry. Instead, "files.source" has been replaced with "files.full".

Example API response snippet before:

"media": [
    {
        "id": 123456,
        "type": "photo",
        "convertedToVideo": False,
        "canView": True,
        "hasError": False,
        "createdAt": "2012-34-56T78:90:12+00:00",
        "files": {
            "source": {
                "source": "https://cdn2.test",
                "width": 2160,
                "height": 2880,
                "size": 0,
                "duration": 0,
            },
            "preview": {"width": 960, "height": 1280, "size": 0},
        },
        "source": {
            "source": "https://cdn2.test",
            "width": 2160,
            "height": 2880,
            "size": 0,
            "duration": 0,
        },
        "squarePreview": "https://cdn2.test",
        "full": "https://cdn2.test",
        "preview": "https://cdn2.test",
        "thumb": "https://cdn2.test",
        "files": {"preview": {"url": "https://cdn2.test"}},
        "videoSources": {"720": None, "240": None},
    }
]

Example API response now:

"media": [
    {
        "id": 123456,
        "type": "photo",
        "convertedToVideo": False,
        "canView": True,
        "hasError": False,
        "createdAt": "2012-34-56T78:90:12+00:00",
        "isReady": true,
        "files": {
            "full": {
                "url": "https://cdn2.test",
                "width": 2160,
                "height": 2880,
                "size": 0
            },
            "preview": {
                "url": "https://cdn2.test",
                "width": 960,
                "height": 513,
                "size": 0
            }
        },
        "duration": 0,
        "hasCustomPreview": false,
        "videoSources": {"720": null, "240": null}
    }
]
datawhores commented 1 month ago

Yeah this should be fixed in 3.11.6 were already getting the urls here

 return {key: (inner_dict or {}).get("url") for key, inner_dict in self._media.get("files",{}).items()}

and getting the full url here

 if quality != "source":
            out=self._media.get("videoSources", {}).get(quality)
        elif out is None:
            out=self.files_source.get("full")
quality != "source"

source comes from click and not the API

datawhores commented 1 month ago

I think this issue is already fixed

Please open new issue if required