Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add streaming download option to Video.bytes() #1186

Merged
merged 1 commit into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions TikTokApi/api/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import requests
from ..exceptions import InvalidResponseException
import json
import httpx
from typing import Union, AsyncIterator

if TYPE_CHECKING:
from ..tiktok import TikTokApi
Expand Down Expand Up @@ -162,7 +164,7 @@ async def info(self, **kwargs) -> dict:
)
return video_info

async def bytes(self, **kwargs) -> bytes:
async def bytes(self, stream: bool = False, **kwargs) -> Union[bytes, AsyncIterator[bytes]]:
"""
Returns the bytes of a TikTok Video.
Expand All @@ -172,13 +174,16 @@ async def bytes(self, **kwargs) -> bytes:
Example Usage:
.. code-block:: python
video_bytes = api.video(id='7041997751718137094').bytes()
video_bytes = await api.video(id='7041997751718137094').bytes()
# Saving The Video
with open('saved_video.mp4', 'wb') as output:
output.write(video_bytes)
"""
# Streaming (if stream=True)
async for chunk in api.video(id='7041997751718137094').bytes(stream=True):
# Process or upload chunk
"""
i, session = self.parent._get_session(**kwargs)
downloadAddr = self.as_dict["video"]["downloadAddr"]

Expand All @@ -189,8 +194,16 @@ async def bytes(self, **kwargs) -> bytes:
h["accept-encoding"] = 'identity;q=1, *;q=0'
h["referer"] = 'https://www.tiktok.com/'

resp = requests.get(downloadAddr, headers=h, cookies=cookies)
return resp.content
if stream:
async def stream_bytes():
async with httpx.AsyncClient() as client:
async with client.stream('GET', downloadAddr, headers=h, cookies=cookies) as response:
async for chunk in response.aiter_bytes():
yield chunk
return stream_bytes()
else:
resp = requests.get(downloadAddr, headers=h, cookies=cookies)
return resp.content

def __extract_from_data(self) -> None:
data = self.as_dict
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
requests>=2.31.0,<3.0
playwright>=1.36.0,<2.0
httpx>=0.27.0,<1.0
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
long_description_content_type="text/markdown",
download_url="https://github.com/davidteather/TikTok-Api/tarball/main",
keywords=["tiktok", "python3", "api", "unofficial", "tiktok-api", "tiktok api"],
install_requires=["requests", "playwright"],
install_requires=["requests", "playwright", "httpx"],
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
Expand Down