Skip to content

Commit 5d90aca

Browse files
update 0.1.1
renew almost all files
1 parent 5b857f1 commit 5d90aca

13 files changed

+263
-16
lines changed

README.md

+13-15
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ import ffmpeg_streaming
5353
There are several ways to open a resource.
5454

5555
#### 1. From a FFmpeg supported resource
56-
You can pass a local path of video(or a supported resource) to the `open` method:
56+
You can pass a local path of video(or a supported resource) to the `input` method:
5757
```python
5858
video = ffmpeg_streaming.input('/var/media/video.mp4')
5959
```
@@ -66,7 +66,7 @@ video = ffmpeg_streaming.input('https://www.aminyazdanpanah.com/?"PATH TO A VIDE
6666
```
6767

6868
#### 2. From Clouds
69-
You can open a file from a cloud by passing an array of cloud configuration to the `openFromCloud` method.
69+
You can open a file from a cloud by passing an instance of a cloud configuration to the `input` method.
7070

7171
```python
7272
from ffmpeg_streaming import S3
@@ -77,10 +77,10 @@ video = ffmpeg_streaming.input(s3, bucket_name="bucket-name", key="video.mp4")
7777
Visit **[this page](https://video.aminyazdanpanah.com/python/start/clouds?r=open)** to see some examples of opening a file from **[Amazon S3](https://aws.amazon.com/s3)**, **[Google Cloud Storage](https://console.cloud.google.com/storage)**, **[Microsoft Azure Storage](https://azure.microsoft.com/en-us/features/storage-explorer/)**, and a custom cloud.
7878

7979
#### 3. Capture Webcam or Screen (Live Streaming)
80-
You can pass a name of the supported, connected capture device(i.e. name of webcam, camera, screen and etc) to the `capture` method to stream a live media over network.
80+
You can pass a name of the supported, connected capture device(i.e. name of webcam, camera, screen and etc) to the `input` method to stream a live media over network.
8181

8282
```python
83-
video = ffmpeg_streaming.input('CAMERA NAME OR SCREEN NAME', capture=True)
83+
capture = ffmpeg_streaming.input('CAMERA NAME OR SCREEN NAME', capture=True)
8484
```
8585
To list the supported, connected capture devices, see **[FFmpeg Capture Webcam](https://trac.ffmpeg.org/wiki/Capture/Webcam)** and **[FFmpeg Capture Desktop](https://trac.ffmpeg.org/wiki/Capture/Desktop)**.
8686

@@ -134,7 +134,7 @@ _360p = Representation(Size(640, 360), Bitrate(276 * 1024, 128 * 1024))
134134
_480p = Representation(Size(854, 480), Bitrate(750 * 1024, 192 * 1024))
135135
_720p = Representation(Size(1280, 720), Bitrate(2048 * 1024, 320 * 1024))
136136

137-
hls = video.hls(Formats.hevc())
137+
hls = video.hls(Formats.h264())
138138
hls.representations(_360p, _480p, _720p)
139139
hls.output('/var/media/hls.m3u8')
140140
```
@@ -174,7 +174,7 @@ See **[the example](https://video.aminyazdanpanah.com/python/start?r=enc-hls#hls
174174
##### DRM
175175
However FFmpeg supports AES encryption for HLS packaging, which you can encrypt your content, it is not a full **[DRM](https://en.wikipedia.org/wiki/Digital_rights_management)** solution. If you want to use a full DRM solution, I recommend trying **[FairPlay Streaming](https://developer.apple.com/streaming/fps/)** solution which then securely exchange keys, and protect playback on devices.
176176

177-
**[Apple’s FairPlay](https://developer.apple.com/streaming/fps/)** is a recommended DRM system, but you can use other DRM systems such as **[Microsoft's PlayReady](https://www.microsoft.com/playready/overview/)** and **[Google’s Widevine](https://www.widevine.com/)**.
177+
**Besides [Apple’s FairPlay](https://developer.apple.com/streaming/fps/)** DRM system, you can also use other DRM systems such as **[Microsoft's PlayReady](https://www.microsoft.com/playready/overview/)** and **[Google’s Widevine](https://www.widevine.com/)**.
178178

179179
### Transcoding
180180
You can get realtime information about the transcoding using the following code.
@@ -208,19 +208,19 @@ dash.auto_generate_representations()
208208

209209
dash.output('/var/media/dash.mpd')
210210
```
211-
It can also be null. The default path to save files is the input path.
212-
``` python
211+
It can also be None. The default path to save files is the input path.
212+
```python
213213
from ffmpeg_streaming import Formats
214214

215215
hls = video.hls(Formats.h264())
216216
hls.auto_generate_representations()
217217

218218
hls.output()
219219
```
220-
**NOTE:** If you open a file from a cloud and do not pass a path to save the file to your local machine, you will have to pass a local path to the `save` method.
220+
**NOTE:** If you open a file from a cloud and do not pass a path to save the file to your local machine, you will have to pass a local path to the `output` method.
221221

222222
#### 2. To Clouds
223-
You can save your files to a cloud by passing an array of cloud configuration to the `save` method.
223+
You can save your files to a cloud by passing an instance of a `CloudManager` to the `output` method.
224224

225225
```python
226226
from ffmpeg_streaming import S3, CloudManager
@@ -244,9 +244,8 @@ Visit **[this page](https://video.aminyazdanpanah.com/python/start/clouds?r=save
244244
<p align="center"><img src="https://github.com/aminyazdanpanah/aminyazdanpanah.github.io/blob/master/video-streaming/video-streaming.gif?raw=true" width="100%"></p>
245245

246246
#### 3. To a Server Instantly
247-
You can pass a url(or a supported resource like `ftp`) to live method to upload all the segments files to the HTTP server(or other protocols) using the HTTP PUT method, and update the manifest files every refresh times.
247+
You can pass a url(or a supported resource like `ftp`) to the `output` method to upload all the segments files to the HTTP server(or other protocols) using the HTTP PUT method, and update the manifest files every refresh times.
248248

249-
If you want to save stream files to your local machine, use the `save` method.
250249

251250
```python
252251
# DASH
@@ -255,7 +254,7 @@ dash.output('http://YOUR-WEBSITE.COM/live-stream/out.mpd')
255254
# HLS
256255
hls.output('http://YOUR-WEBSITE.COM/live-stream/out.m3u8')
257256
```
258-
**NOTE:** In the HLS format, you must upload the master playlist to the server manually. (Upload the `/var/www/stream/live-master-manifest.m3u8` file to the `http://YOUR-WEBSITE.COM`)
257+
**NOTE:** In the HLS format, you must upload the master playlist to the server manually.
259258

260259
See **[FFmpeg Protocols Documentation](https://ffmpeg.org/ffmpeg-protocols.html)** for more information.
261260

@@ -270,7 +269,7 @@ ffprobe = FFProbe('/var/media/video.mp4')
270269
See **[the example](https://video.aminyazdanpanah.com/python/start?r=metadata#metadata)** for more information.
271270

272271
### Conversion
273-
You can convert your stream to a file or to another stream protocols. You should pass a manifest of the stream to the `open` method:
272+
You can convert your stream to a file or to another stream protocols. You should pass a manifest of the stream to the `input` method:
274273

275274
#### 1. HLS To DASH
276275
```python
@@ -300,7 +299,6 @@ video = ffmpeg_streaming.input('https://www.aminyazdanpanah.com/?PATH/TO/MANIFES
300299

301300
stream = video.stream2file(Formats.h264())
302301
stream.output('/var/media/new-video.mp4')
303-
304302
```
305303

306304
## Several Open Source Players

ffmpeg_streaming/_clouds.py

+15
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020

2121
class Clouds(abc.ABC):
22+
"""
23+
@TODO: add documentation
24+
"""
2225
@abc.abstractmethod
2326
def upload_directory(self, directory: str, **options) -> None:
2427
pass
@@ -30,6 +33,9 @@ def download(self, filename: str = None, **options) -> str:
3033

3134
class S3(Clouds):
3235
def __init__(self, **options):
36+
"""
37+
@TODO: add documentation
38+
"""
3339
try:
3440
import boto3
3541
from botocore.exceptions import ClientError
@@ -81,6 +87,9 @@ def download(self, filename=None, **options):
8187

8288
class GCS(Clouds):
8389
def __init__(self, **options):
90+
"""
91+
@TODO: add documentation
92+
"""
8493
try:
8594
from google.cloud import storage
8695
except ImportError as e:
@@ -124,6 +133,9 @@ def download(self, filename=None, **options):
124133

125134
class MAS(Clouds):
126135
def __init__(self, **options):
136+
"""
137+
@TODO: add documentation
138+
"""
127139
try:
128140
from azure.storage.blob import BlockBlobService
129141
except ImportError as e:
@@ -170,6 +182,9 @@ def download(self, filename=None, **options):
170182

171183
class CloudManager:
172184
def __init__(self):
185+
"""
186+
@TODO: add documentation
187+
"""
173188
self.clouds = []
174189

175190
def add(self, cloud: Clouds, **options):

ffmpeg_streaming/_command_builder.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def _get_hls_stream(hls, rep, dirname, name):
7777
'b:a': rep.bitrate.audio,
7878
'maxrate': rep.bitrate.max_rate,
7979
'hls_segment_filename': dirname + "/" + name + "_" + str(rep.size.height) + "p_%04d." + _hls_seg_ext(hls),
80-
'hls_fmp4_init_filename': name + "_init.mp4",
80+
'hls_fmp4_init_filename': name + "_" + str(rep.size.height) + "p_init.mp4",
8181
'strict': '-2'
8282
}
8383
args.update(hls.options)
@@ -86,6 +86,9 @@ def _get_hls_stream(hls, rep, dirname, name):
8686

8787

8888
def _hls(hls):
89+
"""
90+
@TODO: add documentation
91+
"""
8992
dirname, name = get_path_info(hls.output_)
9093
streams = []
9194
for rep in hls.reps:
@@ -95,10 +98,16 @@ def _hls(hls):
9598

9699

97100
def stream_args(media):
101+
"""
102+
@TODO: add documentation
103+
"""
98104
return getattr(sys.modules[__name__], "_%s" % type(media).__name__.lower())(media)
99105

100106

101107
def command_builder(ffmpeg_bin: str, media):
108+
"""
109+
@TODO: add documentation
110+
"""
102111
args = [ffmpeg_bin] + cnv_options_to_args(dict(media.media.input_opts)) + stream_args(media)
103112
return " ".join(clean_args(args))
104113

ffmpeg_streaming/_format.py

+21
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ def _verify_codecs(codec, codecs):
3030

3131

3232
class Format(abc.ABC):
33+
"""
34+
@TODO: add documentation
35+
"""
3336
def __init__(self, video: str, audio: str):
3437
self.video = video
3538
self.audio = audio
@@ -40,6 +43,9 @@ def multiply(self) -> int:
4043

4144

4245
class H264(Format):
46+
"""
47+
@TODO: add documentation
48+
"""
4349
def __init__(self, video: str = "libx264", audio: str = 'copy'):
4450
videos = ['libx264', 'h264', 'h264_afm']
4551
audios = ['copy', 'aac', 'libvo_aacenc', 'libfaac', 'libmp3lame', 'libfdk_aac']
@@ -51,6 +57,9 @@ def multiply(self) -> int:
5157

5258

5359
class HEVC(Format):
60+
"""
61+
@TODO: add documentation
62+
"""
5463
def __init__(self, video: str = "libx265", audio: str = 'copy'):
5564
videos = ['libx265', 'h265']
5665
audios = ['copy', 'aac', 'libvo_aacenc', 'libfaac', 'libmp3lame', 'libfdk_aac']
@@ -62,6 +71,9 @@ def multiply(self) -> int:
6271

6372

6473
class VP9(Format):
74+
"""
75+
@TODO: add documentation
76+
"""
6577
def __init__(self, video: str = "libvpx-vp9", audio: str = 'copy'):
6678
videos = ['libvpx', 'libvpx-vp9']
6779
audios = ['copy', 'aac', 'libvo_aacenc', 'libfaac', 'libmp3lame', 'libfdk_aac']
@@ -75,14 +87,23 @@ def multiply(self) -> int:
7587
class Formats:
7688
@staticmethod
7789
def h264(video: str = "libx264", audio: str = 'copy') -> Format:
90+
"""
91+
@TODO: add documentation
92+
"""
7893
return H264(video, audio)
7994

8095
@staticmethod
8196
def hevc(video: str = "libx265", audio: str = 'copy') -> Format:
97+
"""
98+
@TODO: add documentation
99+
"""
82100
return HEVC(video, audio)
83101

84102
@staticmethod
85103
def vp9(video: str = "libvpx-vp9", audio: str = 'copy') -> Format:
104+
"""
105+
@TODO: add documentation
106+
"""
86107
return VP9(video, audio)
87108

88109

ffmpeg_streaming/_hls_helper.py

+9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
class HLSKeyInfoFile:
2121
def __init__(self, key_info_file_path: str, path: str, url: str, period: int = 0, needle: str = '', length: int = 16):
22+
"""
23+
@TODO: add documentation
24+
"""
2225
self.needle = needle
2326
self.period = period
2427
self.segments = []
@@ -71,6 +74,9 @@ def stream_info(rep) -> list:
7174

7275
class HLSMasterPlaylist:
7376
def __init__(self, media):
77+
"""
78+
@TODO: add documentation
79+
"""
7480
self.media = media
7581
self.path = media.output
7682

@@ -81,6 +87,9 @@ def generate(cls, media):
8187
playlist.write(cls(media)._content())
8288

8389
def _content(self) -> str:
90+
"""
91+
@TODO: add documentation
92+
"""
8493
content = ['#EXTM3U'] + self._get_version() + self.media.options.get('description', [])
8594

8695
for rep in self.media.reps:

ffmpeg_streaming/_input.py

+9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
class Capture(object):
1919
def __init__(self, video, options):
20+
"""
21+
@TODO: add documentation
22+
"""
2023
self.options = options
2124
self.video = video
2225

@@ -58,6 +61,9 @@ def __iter__(self):
5861

5962

6063
def get_from_cloud(cloud: Clouds, options: dict):
64+
"""
65+
@TODO: add documentation
66+
"""
6167
save_to = options.pop('save_to', None)
6268
return {
6369
'i': cloud.download(save_to, **options),
@@ -67,6 +73,9 @@ def get_from_cloud(cloud: Clouds, options: dict):
6773

6874
class InputOption(object):
6975
def __init__(self, _input, **options):
76+
"""
77+
@TODO: add documentation
78+
"""
7079
self.input_ = _input
7180
self.options = options
7281

0 commit comments

Comments
 (0)