TonieToolbox 0.5.1__py3-none-any.whl → 0.6.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,27 +19,33 @@ DEFAULT_RETRY_DELAY = 5 # seconds
19
19
  class TeddyCloudClient:
20
20
  """Client for interacting with TeddyCloud API."""
21
21
 
22
- def __init__(self, base_url: str, ignore_ssl_verify: bool = False,
23
- connection_timeout: int = DEFAULT_CONNECTION_TIMEOUT,
24
- read_timeout: int = DEFAULT_READ_TIMEOUT,
25
- max_retries: int = DEFAULT_MAX_RETRIES,
26
- retry_delay: int = DEFAULT_RETRY_DELAY,
27
- username: str = None, password: str = None,
28
- cert_file: str = None, key_file: str = None):
22
+ def __init__(
23
+ self,
24
+ base_url: str,
25
+ ignore_ssl_verify: bool = False,
26
+ connection_timeout: int = DEFAULT_CONNECTION_TIMEOUT,
27
+ read_timeout: int = DEFAULT_READ_TIMEOUT,
28
+ max_retries: int = DEFAULT_MAX_RETRIES,
29
+ retry_delay: int = DEFAULT_RETRY_DELAY,
30
+ username: str = None,
31
+ password: str = None,
32
+ cert_file: str = None,
33
+ key_file: str = None
34
+ ) -> None:
29
35
  """
30
36
  Initialize the TeddyCloud client.
31
37
 
32
38
  Args:
33
- base_url: Base URL of the TeddyCloud instance (e.g., https://teddycloud.example.com)
34
- ignore_ssl_verify: If True, SSL certificate verification will be disabled (useful for self-signed certificates)
35
- connection_timeout: Timeout for establishing a connection
36
- read_timeout: Timeout for reading data from the server
37
- max_retries: Maximum number of retries for failed requests
38
- retry_delay: Delay between retries
39
- username: Username for basic authentication (optional)
40
- password: Password for basic authentication (optional)
41
- cert_file: Path to client certificate file for certificate-based authentication (optional)
42
- key_file: Path to client private key file for certificate-based authentication (optional)
39
+ base_url (str): Base URL of the TeddyCloud instance (e.g., https://teddycloud.example.com)
40
+ ignore_ssl_verify (bool): If True, SSL certificate verification will be disabled (useful for self-signed certificates)
41
+ connection_timeout (int): Timeout for establishing a connection
42
+ read_timeout (int): Timeout for reading data from the server
43
+ max_retries (int): Maximum number of retries for failed requests
44
+ retry_delay (int): Delay between retries
45
+ username (str | None): Username for basic authentication (optional)
46
+ password (str | None): Password for basic authentication (optional)
47
+ cert_file (str | None): Path to client certificate file for certificate-based authentication (optional)
48
+ key_file (str | None): Path to client private key file for certificate-based authentication (optional)
43
49
  """
44
50
  self.base_url = base_url.rstrip('/')
45
51
  self.ignore_ssl_verify = ignore_ssl_verify
@@ -81,7 +87,7 @@ class TeddyCloudClient:
81
87
  except ssl.SSLError as e:
82
88
  raise ValueError(f"Failed to load client certificate: {e}")
83
89
 
84
- def _create_request_kwargs(self):
90
+ def _create_request_kwargs(self) -> dict:
85
91
  """
86
92
  Create common request keyword arguments for all API calls.
87
93
 
@@ -98,18 +104,16 @@ class TeddyCloudClient:
98
104
  kwargs['cert'] = self.cert
99
105
  return kwargs
100
106
 
101
- def _make_request(self, method, endpoint, **kwargs):
107
+ def _make_request(self, method: str, endpoint: str, **kwargs) -> 'requests.Response':
102
108
  """
103
109
  Make an HTTP request to the TeddyCloud API with retry logic.
104
110
 
105
111
  Args:
106
- method: HTTP method (GET, POST, etc.)
107
- endpoint: API endpoint (without base URL)
112
+ method (str): HTTP method (GET, POST, etc.)
113
+ endpoint (str): API endpoint (without base URL)
108
114
  **kwargs: Additional arguments to pass to requests
109
-
110
115
  Returns:
111
116
  requests.Response: Response object
112
-
113
117
  Raises:
114
118
  requests.exceptions.RequestException: If request fails after all retries
115
119
  """
@@ -171,7 +175,7 @@ class TeddyCloudClient:
171
175
 
172
176
  # ------------- GET API Methods -------------
173
177
 
174
- def get_tonies_custom_json(self):
178
+ def get_tonies_custom_json(self) -> dict:
175
179
  """
176
180
  Get custom Tonies JSON data from the TeddyCloud server.
177
181
 
@@ -181,7 +185,7 @@ class TeddyCloudClient:
181
185
  response = self._make_request('GET', '/api/toniesCustomJson')
182
186
  return response.json()
183
187
 
184
- def get_tonies_json(self):
188
+ def get_tonies_json(self) -> dict:
185
189
  """
186
190
  Get Tonies JSON data from the TeddyCloud server.
187
191
 
@@ -191,7 +195,7 @@ class TeddyCloudClient:
191
195
  response = self._make_request('GET', '/api/toniesJson')
192
196
  return response.json()
193
197
 
194
- def get_tag_index(self):
198
+ def get_tag_index(self) -> dict:
195
199
  """
196
200
  Get tag index data from the TeddyCloud server.
197
201
 
@@ -201,7 +205,7 @@ class TeddyCloudClient:
201
205
  response = self._make_request('GET', '/api/getTagIndex')
202
206
  return response.json()
203
207
 
204
- def get_file_index(self):
208
+ def get_file_index(self) -> dict:
205
209
  """
206
210
  Get file index data from the TeddyCloud server.
207
211
 
@@ -211,7 +215,7 @@ class TeddyCloudClient:
211
215
  response = self._make_request('GET', '/api/fileIndex')
212
216
  return response.json()
213
217
 
214
- def get_file_index_v2(self):
218
+ def get_file_index_v2(self) -> dict:
215
219
  """
216
220
  Get version 2 file index data from the TeddyCloud server.
217
221
 
@@ -221,7 +225,7 @@ class TeddyCloudClient:
221
225
  response = self._make_request('GET', '/api/fileIndexV2')
222
226
  return response.json()
223
227
 
224
- def get_tonieboxes_json(self):
228
+ def get_tonieboxes_json(self) -> dict:
225
229
  """
226
230
  Get Tonieboxes JSON data from the TeddyCloud server.
227
231
 
@@ -233,15 +237,14 @@ class TeddyCloudClient:
233
237
 
234
238
  # ------------- POST API Methods -------------
235
239
 
236
- def create_directory(self, path, overlay=None, special=None):
240
+ def create_directory(self, path: str, overlay: str = None, special: str = None) -> str:
237
241
  """
238
242
  Create a directory on the TeddyCloud server.
239
243
 
240
244
  Args:
241
- path: Directory path to create
242
- overlay: Settings overlay ID (optional)
243
- special: Special folder source, only 'library' supported yet (optional)
244
-
245
+ path (str): Directory path to create
246
+ overlay (str | None): Settings overlay ID (optional)
247
+ special (str | None): Special folder source, only 'library' supported yet (optional)
245
248
  Returns:
246
249
  str: Response message from server (usually "OK")
247
250
  """
@@ -254,15 +257,14 @@ class TeddyCloudClient:
254
257
  response = self._make_request('POST', '/api/dirCreate', params=params, data=path)
255
258
  return response.text
256
259
 
257
- def delete_directory(self, path, overlay=None, special=None):
260
+ def delete_directory(self, path: str, overlay: str = None, special: str = None) -> str:
258
261
  """
259
262
  Delete a directory from the TeddyCloud server.
260
263
 
261
264
  Args:
262
- path: Directory path to delete
263
- overlay: Settings overlay ID (optional)
264
- special: Special folder source, only 'library' supported yet (optional)
265
-
265
+ path (str): Directory path to delete
266
+ overlay (str | None): Settings overlay ID (optional)
267
+ special (str | None): Special folder source, only 'library' supported yet (optional)
266
268
  Returns:
267
269
  str: Response message from server (usually "OK")
268
270
  """
@@ -275,15 +277,14 @@ class TeddyCloudClient:
275
277
  response = self._make_request('POST', '/api/dirDelete', params=params, data=path)
276
278
  return response.text
277
279
 
278
- def delete_file(self, path, overlay=None, special=None):
280
+ def delete_file(self, path: str, overlay: str = None, special: str = None) -> str:
279
281
  """
280
282
  Delete a file from the TeddyCloud server.
281
283
 
282
284
  Args:
283
- path: File path to delete
284
- overlay: Settings overlay ID (optional)
285
- special: Special folder source, only 'library' supported yet (optional)
286
-
285
+ path (str): File path to delete
286
+ overlay (str | None): Settings overlay ID (optional)
287
+ special (str | None): Special folder source, only 'library' supported yet (optional)
287
288
  Returns:
288
289
  str: Response message from server (usually "OK")
289
290
  """
@@ -296,16 +297,15 @@ class TeddyCloudClient:
296
297
  response = self._make_request('POST', '/api/fileDelete', params=params, data=path)
297
298
  return response.text
298
299
 
299
- def upload_file(self, file_path, destination_path=None, overlay=None, special=None):
300
+ def upload_file(self, file_path: str, destination_path: str = None, overlay: str = None, special: str = None) -> dict:
300
301
  """
301
302
  Upload a file to the TeddyCloud server.
302
303
 
303
304
  Args:
304
- file_path: Local path to the file to upload
305
- destination_path: Server path where to write the file to (optional)
306
- overlay: Settings overlay ID (optional)
307
- special: Special folder source, only 'library' supported yet (optional)
308
-
305
+ file_path (str): Local path to the file to upload
306
+ destination_path (str | None): Server path where to write the file to (optional)
307
+ overlay (str | None): Settings overlay ID (optional)
308
+ special (str | None): Special folder source, only 'library' supported yet (optional)
309
309
  Returns:
310
310
  dict: JSON response from server
311
311
  """
@@ -11,12 +11,13 @@ from .ogg_page import OggPage
11
11
  from .logger import get_logger
12
12
 
13
13
  logger = get_logger('tonie_analysis')
14
- def format_time(ts):
14
+
15
+ def format_time(ts: float) -> str:
15
16
  """
16
17
  Format a timestamp as a human-readable date and time string.
17
18
 
18
19
  Args:
19
- ts: Timestamp to format
20
+ ts (float): Timestamp to format
20
21
 
21
22
  Returns:
22
23
  str: Formatted date and time string
@@ -24,12 +25,12 @@ def format_time(ts):
24
25
  return datetime.datetime.fromtimestamp(ts, datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S')
25
26
 
26
27
 
27
- def format_hex(data):
28
+ def format_hex(data: bytes) -> str:
28
29
  """
29
30
  Format binary data as a hex string.
30
31
 
31
32
  Args:
32
- data: Binary data to format
33
+ data (bytes): Binary data to format
33
34
 
34
35
  Returns:
35
36
  str: Formatted hex string
@@ -37,13 +38,13 @@ def format_hex(data):
37
38
  return "".join(format(x, "02X") for x in data)
38
39
 
39
40
 
40
- def granule_to_time_string(granule, sample_rate=1):
41
+ def granule_to_time_string(granule: int, sample_rate: int = 1) -> str:
41
42
  """
42
43
  Convert a granule position to a time string.
43
44
 
44
45
  Args:
45
- granule: Granule position
46
- sample_rate: Sample rate in Hz
46
+ granule (int): Granule position
47
+ sample_rate (int): Sample rate in Hz
47
48
 
48
49
  Returns:
49
50
  str: Formatted time string (HH:MM:SS.FF)
@@ -56,7 +57,7 @@ def granule_to_time_string(granule, sample_rate=1):
56
57
  return "{:02d}:{:02d}:{:02d}.{:02d}".format(hours, minutes, seconds, fraction)
57
58
 
58
59
 
59
- def get_header_info(in_file):
60
+ def get_header_info(in_file) -> tuple:
60
61
  """
61
62
  Get header information from a Tonie file.
62
63
 
@@ -164,15 +165,15 @@ def get_header_info(in_file):
164
165
  )
165
166
 
166
167
 
167
- def get_audio_info(in_file, sample_rate, tonie_header, header_size):
168
+ def get_audio_info(in_file, sample_rate: int, tonie_header, header_size: int) -> tuple:
168
169
  """
169
170
  Get audio information from a Tonie file.
170
171
 
171
172
  Args:
172
173
  in_file: Input file handle
173
- sample_rate: Sample rate in Hz
174
+ sample_rate (int): Sample rate in Hz
174
175
  tonie_header: Tonie header object
175
- header_size: Header size in bytes
176
+ header_size (int): Header size in bytes
176
177
 
177
178
  Returns:
178
179
  tuple: Page count, alignment OK flag, page size OK flag, total time, chapter times
@@ -228,12 +229,12 @@ def get_audio_info(in_file, sample_rate, tonie_header, header_size):
228
229
  return page_count, alignment_okay, page_size_okay, total_time, chapter_times
229
230
 
230
231
 
231
- def check_tonie_file(filename):
232
+ def check_tonie_file(filename: str) -> bool:
232
233
  """
233
234
  Check if a file is a valid Tonie file and display information about it.
234
235
 
235
236
  Args:
236
- filename: Path to the file to check
237
+ filename (str): Path to the file to check
237
238
 
238
239
  Returns:
239
240
  bool: True if the file is valid, False otherwise
@@ -315,13 +316,13 @@ def check_tonie_file(filename):
315
316
  return all_ok
316
317
 
317
318
 
318
- def split_to_opus_files(filename, output=None):
319
+ def split_to_opus_files(filename: str, output: str = None) -> None:
319
320
  """
320
321
  Split a Tonie file into individual Opus files.
321
322
 
322
323
  Args:
323
- filename: Path to the Tonie file
324
- output: Output directory path (optional)
324
+ filename (str): Path to the Tonie file
325
+ output (str | None): Output directory path (optional)
325
326
  """
326
327
  logger.info("Splitting Tonie file into individual Opus tracks: %s", filename)
327
328
 
@@ -412,14 +413,14 @@ def split_to_opus_files(filename, output=None):
412
413
  logger.info("Successfully split Tonie file into %d individual tracks", len(tonie_header.chapterPages))
413
414
 
414
415
 
415
- def compare_taf_files(file1, file2, detailed=False):
416
+ def compare_taf_files(file1: str, file2: str, detailed: bool = False) -> bool:
416
417
  """
417
418
  Compare two .taf files for debugging purposes.
418
419
 
419
420
  Args:
420
- file1: Path to the first .taf file
421
- file2: Path to the second .taf file
422
- detailed: Whether to show detailed comparison results
421
+ file1 (str): Path to the first .taf file
422
+ file2 (str): Path to the second .taf file
423
+ detailed (bool): Whether to show detailed comparison results
423
424
 
424
425
  Returns:
425
426
  bool: True if files are equivalent, False otherwise
@@ -572,7 +573,7 @@ def compare_taf_files(file1, file2, detailed=False):
572
573
  logger.info("Files comparison result: Equivalent")
573
574
  return True
574
575
 
575
- def get_header_info_cli(in_file):
576
+ def get_header_info_cli(in_file) -> tuple:
576
577
  """
577
578
  Get header information from a Tonie file.
578
579
 
@@ -687,12 +688,12 @@ def get_header_info_cli(in_file):
687
688
  return (0, tonie_header_pb2.TonieHeader(), 0, 0, None, False, 0, 0, 0, 0, {}, False)
688
689
 
689
690
 
690
- def check_tonie_file_cli(filename):
691
+ def check_tonie_file_cli(filename: str) -> bool:
691
692
  """
692
693
  Check if a file is a valid Tonie file
693
694
 
694
695
  Args:
695
- filename: Path to the file to check
696
+ filename (str): Path to the file to check
696
697
 
697
698
  Returns:
698
699
  bool: True if the file is valid, False otherwise
@@ -18,14 +18,14 @@ from .logger import get_logger
18
18
  logger = get_logger('tonie_file')
19
19
 
20
20
 
21
- def toniefile_comment_add(buffer, length, comment_str):
21
+ def toniefile_comment_add(buffer: bytearray, length: int, comment_str: str) -> int:
22
22
  """
23
23
  Add a comment string to an Opus comment packet buffer.
24
24
 
25
25
  Args:
26
- buffer: Bytearray buffer to add comment to
27
- length: Current position in the buffer
28
- comment_str: Comment string to add
26
+ buffer (bytearray): Bytearray buffer to add comment to
27
+ length (int): Current position in the buffer
28
+ comment_str (str): Comment string to add
29
29
 
30
30
  Returns:
31
31
  int: New position in the buffer after adding comment
@@ -44,7 +44,7 @@ def toniefile_comment_add(buffer, length, comment_str):
44
44
  return length
45
45
 
46
46
 
47
- def check_identification_header(page):
47
+ def check_identification_header(page) -> None:
48
48
  """
49
49
  Check if a page contains a valid Opus identification header.
50
50
 
@@ -77,16 +77,16 @@ def check_identification_header(page):
77
77
  logger.debug("Opus identification header is valid")
78
78
 
79
79
 
80
- def prepare_opus_tags(page, custom_tags=False, bitrate=64, vbr=True, opus_binary=None):
80
+ def prepare_opus_tags(page, custom_tags: bool = False, bitrate: int = 64, vbr: bool = True, opus_binary: str = None) -> OggPage:
81
81
  """
82
82
  Prepare standard Opus tags for a Tonie file.
83
83
 
84
84
  Args:
85
85
  page: OggPage to modify
86
- custom_tags: Whether to use custom TonieToolbox tags instead of default ones
87
- bitrate: Actual bitrate used for encoding
88
- vbr: Whether variable bitrate was used
89
- opus_binary: Path to opusenc binary for version detection
86
+ custom_tags (bool): Whether to use custom TonieToolbox tags instead of default ones
87
+ bitrate (int): Actual bitrate used for encoding
88
+ vbr (bool): Whether variable bitrate was used
89
+ opus_binary (str | None): Path to opusenc binary for version detection
90
90
 
91
91
  Returns:
92
92
  OggPage: Modified page with Tonie-compatible Opus tags
@@ -162,19 +162,28 @@ def prepare_opus_tags(page, custom_tags=False, bitrate=64, vbr=True, opus_binary
162
162
  return page
163
163
 
164
164
 
165
- def copy_first_and_second_page(in_file, out_file, timestamp, sha, use_custom_tags=True, bitrate=64, vbr=True, opus_binary=None):
165
+ def copy_first_and_second_page(
166
+ in_file,
167
+ out_file,
168
+ timestamp: int,
169
+ sha,
170
+ use_custom_tags: bool = True,
171
+ bitrate: int = 64,
172
+ vbr: bool = True,
173
+ opus_binary: str = None
174
+ ) -> None:
166
175
  """
167
176
  Copy and modify the first two pages of an Opus file for a Tonie file.
168
177
 
169
178
  Args:
170
179
  in_file: Input file handle
171
180
  out_file: Output file handle
172
- timestamp: Timestamp to use for the Tonie file
181
+ timestamp (int): Timestamp to use for the Tonie file
173
182
  sha: SHA1 hash object to update with written data
174
- use_custom_tags: Whether to use custom TonieToolbox tags
175
- bitrate: Actual bitrate used for encoding
176
- vbr: Whether VBR was used
177
- opus_binary: Path to opusenc binary
183
+ use_custom_tags (bool): Whether to use custom TonieToolbox tags
184
+ bitrate (int): Actual bitrate used for encoding
185
+ vbr (bool): Whether VBR was used
186
+ opus_binary (str | None): Path to opusenc binary
178
187
  """
179
188
  logger.debug("Copying first and second pages with timestamp %d", timestamp)
180
189
  found = OggPage.seek_to_page_header(in_file)
@@ -202,7 +211,7 @@ def copy_first_and_second_page(in_file, out_file, timestamp, sha, use_custom_tag
202
211
  logger.debug("Second page written successfully")
203
212
 
204
213
 
205
- def skip_first_two_pages(in_file):
214
+ def skip_first_two_pages(in_file) -> None:
206
215
  """
207
216
  Skip the first two pages of an Opus file.
208
217
 
@@ -235,7 +244,7 @@ def skip_first_two_pages(in_file):
235
244
  logger.debug("First two pages skipped successfully")
236
245
 
237
246
 
238
- def read_all_remaining_pages(in_file):
247
+ def read_all_remaining_pages(in_file) -> list:
239
248
  """
240
249
  Read all remaining OGG pages from an input file.
241
250
 
@@ -260,19 +269,26 @@ def read_all_remaining_pages(in_file):
260
269
  return remaining_pages
261
270
 
262
271
 
263
- def resize_pages(old_pages, max_page_size, first_page_size, template_page, last_granule=0, start_no=2,
264
- set_last_page_flag=False):
272
+ def resize_pages(
273
+ old_pages: list,
274
+ max_page_size: int,
275
+ first_page_size: int,
276
+ template_page,
277
+ last_granule: int = 0,
278
+ start_no: int = 2,
279
+ set_last_page_flag: bool = False
280
+ ) -> list:
265
281
  """
266
282
  Resize OGG pages to fit Tonie requirements.
267
283
 
268
284
  Args:
269
- old_pages: List of original OggPage objects
270
- max_page_size: Maximum size for pages
271
- first_page_size: Size for the first page
285
+ old_pages (list): List of original OggPage objects
286
+ max_page_size (int): Maximum size for pages
287
+ first_page_size (int): Size for the first page
272
288
  template_page: Template OggPage to use for creating new pages
273
- last_granule: Last granule position
274
- start_no: Starting page number
275
- set_last_page_flag: Whether to set the last page flag
289
+ last_granule (int): Last granule position
290
+ start_no (int): Starting page number
291
+ set_last_page_flag (bool): Whether to set the last page flag
276
292
 
277
293
  Returns:
278
294
  list: List of resized OggPage objects
@@ -326,14 +342,14 @@ def resize_pages(old_pages, max_page_size, first_page_size, template_page, last_
326
342
  return new_pages
327
343
 
328
344
 
329
- def fix_tonie_header(out_file, chapters, timestamp, sha):
345
+ def fix_tonie_header(out_file, chapters: list, timestamp: int, sha) -> None:
330
346
  """
331
347
  Fix the Tonie header in a file.
332
348
 
333
349
  Args:
334
350
  out_file: Output file handle
335
- chapters: List of chapter page numbers
336
- timestamp: Timestamp for the Tonie file
351
+ chapters (list): List of chapter page numbers
352
+ timestamp (int): Timestamp for the Tonie file
337
353
  sha: SHA1 hash object with file content
338
354
  """
339
355
  logger.info("Writing Tonie header with %d chapters and timestamp %d", len(chapters), timestamp)
@@ -362,25 +378,36 @@ def fix_tonie_header(out_file, chapters, timestamp, sha):
362
378
  logger.debug("Tonie header written successfully (size: %d bytes)", len(header))
363
379
 
364
380
 
365
- def create_tonie_file(output_file, input_files, no_tonie_header=False, user_timestamp=None,
366
- bitrate=96, vbr=True, ffmpeg_binary=None, opus_binary=None, keep_temp=False, auto_download=False,
367
- use_custom_tags=True, no_mono_conversion=False):
381
+ def create_tonie_file(
382
+ output_file: str,
383
+ input_files: list[str],
384
+ no_tonie_header: bool = False,
385
+ user_timestamp: str = None,
386
+ bitrate: int = 96,
387
+ vbr: bool = True,
388
+ ffmpeg_binary: str = None,
389
+ opus_binary: str = None,
390
+ keep_temp: bool = False,
391
+ auto_download: bool = False,
392
+ use_custom_tags: bool = True,
393
+ no_mono_conversion: bool = False
394
+ ) -> None:
368
395
  """
369
396
  Create a Tonie file from input files.
370
397
 
371
398
  Args:
372
- output_file: Output file path
373
- input_files: List of input file paths
374
- no_tonie_header: Whether to omit the Tonie header
375
- user_timestamp: Custom timestamp to use
376
- bitrate: Bitrate for encoding in kbps
377
- vbr: Whether to use variable bitrate encoding (True) or constant (False)
378
- ffmpeg_binary: Path to ffmpeg binary
379
- opus_binary: Path to opusenc binary
380
- keep_temp: Whether to keep temporary opus files for testing
381
- auto_download: Whether to automatically download dependencies if not found
382
- use_custom_tags: Whether to use dynamic comment tags generated with toniefile_comment_add
383
- no_mono_conversion: Whether to skip mono conversion during audio processing
399
+ output_file (str): Output file path
400
+ input_files (list[str]): List of input file paths
401
+ no_tonie_header (bool): Whether to omit the Tonie header
402
+ user_timestamp (str | None): Custom timestamp to use
403
+ bitrate (int): Bitrate for encoding in kbps
404
+ vbr (bool): Whether to use variable bitrate encoding (True) or constant (False)
405
+ ffmpeg_binary (str | None): Path to ffmpeg binary
406
+ opus_binary (str | None): Path to opusenc binary
407
+ keep_temp (bool): Whether to keep temporary opus files for testing
408
+ auto_download (bool): Whether to automatically download dependencies if not found
409
+ use_custom_tags (bool): Whether to use dynamic comment tags generated with toniefile_comment_add
410
+ no_mono_conversion (bool): Whether to skip mono conversion during audio processing
384
411
  """
385
412
  from .audio_conversion import get_opus_tempfile
386
413