or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

analysis-visualization.mdexecution.mdindex.mdinput-output.mdstream-processing.mdvideo-filters.md

execution.mddocs/

0

# Execution and Control

1

2

Functions for executing FFmpeg commands synchronously or asynchronously, building command-line arguments, and handling process control with comprehensive error management.

3

4

## Capabilities

5

6

### Synchronous Execution

7

8

Execute FFmpeg commands and wait for completion with comprehensive output capture and error handling.

9

10

```python { .api }

11

def run(stream_spec, cmd: str = 'ffmpeg', capture_stdout: bool = False, capture_stderr: bool = False, input=None, quiet: bool = False, overwrite_output: bool = False) -> tuple:

12

"""

13

Invoke FFmpeg for the supplied node graph and wait for completion.

14

15

Parameters:

16

- stream_spec: Stream or stream specification to execute

17

- cmd: str, FFmpeg command path (default: 'ffmpeg')

18

- capture_stdout: bool, capture stdout for pipe: outputs

19

- capture_stderr: bool, capture stderr for debugging

20

- input: bytes, data to send to stdin for pipe: inputs

21

- quiet: bool, suppress output (sets capture_stdout and capture_stderr)

22

- overwrite_output: bool, add -y flag to overwrite existing files

23

24

Returns:

25

tuple: (stdout_data, stderr_data) as bytes objects

26

27

Raises:

28

ffmpeg.Error: if FFmpeg returns non-zero exit code

29

"""

30

```

31

32

**Usage Example:**

33

```python

34

import ffmpeg

35

36

# Simple execution

37

stream = ffmpeg.input('input.mp4').hflip().output('output.mp4')

38

ffmpeg.run(stream)

39

40

# Execution with output capture

41

try:

42

stdout, stderr = ffmpeg.run(

43

stream,

44

capture_stdout=True,

45

capture_stderr=True

46

)

47

print("Command succeeded")

48

except ffmpeg.Error as e:

49

print(f"Command failed: {e}")

50

print(f"stderr: {e.stderr.decode()}")

51

52

# Quiet execution (suppress all output)

53

ffmpeg.run(stream, quiet=True, overwrite_output=True)

54

```

55

56

### Asynchronous Execution

57

58

Start FFmpeg processes without waiting for completion, enabling real-time processing and pipeline control.

59

60

```python { .api }

61

def run_async(stream_spec, cmd: str = 'ffmpeg', pipe_stdin: bool = False, pipe_stdout: bool = False, pipe_stderr: bool = False, quiet: bool = False, overwrite_output: bool = False):

62

"""

63

Asynchronously invoke FFmpeg for the supplied node graph.

64

65

Parameters:

66

- stream_spec: Stream or stream specification to execute

67

- cmd: str, FFmpeg command path (default: 'ffmpeg')

68

- pipe_stdin: bool, connect pipe to subprocess stdin

69

- pipe_stdout: bool, connect pipe to subprocess stdout

70

- pipe_stderr: bool, connect pipe to subprocess stderr

71

- quiet: bool, shorthand for pipe_stdout and pipe_stderr

72

- overwrite_output: bool, add -y flag to overwrite existing files

73

74

Returns:

75

subprocess.Popen: Process object for the running FFmpeg command

76

"""

77

```

78

79

**Usage Example:**

80

```python

81

import subprocess

82

83

# Basic async execution

84

stream = ffmpeg.input('input.mp4').output('output.mp4')

85

process = ffmpeg.run_async(stream)

86

process.wait() # Wait for completion

87

88

# Streaming input and output

89

input_stream = ffmpeg.input('pipe:', format='rawvideo', pix_fmt='rgb24', s='640x480')

90

output_stream = ffmpeg.output(input_stream, 'pipe:', format='rawvideo', pix_fmt='yuv420p')

91

92

process = ffmpeg.run_async(

93

output_stream,

94

pipe_stdin=True,

95

pipe_stdout=True

96

)

97

98

# Send data and receive results

99

stdout, stderr = process.communicate(input=raw_video_data)

100

101

# Real-time processing example

102

process1 = ffmpeg.run_async(

103

ffmpeg.input('input.mp4').output('pipe:', format='rawvideo'),

104

pipe_stdout=True

105

)

106

107

process2 = ffmpeg.run_async(

108

ffmpeg.input('pipe:', format='rawvideo', s='1920x1080').output('processed.mp4'),

109

pipe_stdin=True

110

)

111

112

# Stream data between processes

113

while True:

114

chunk = process1.stdout.read(1920 * 1080 * 3) # One frame

115

if not chunk:

116

break

117

process2.stdin.write(chunk)

118

119

process2.stdin.close()

120

process1.wait()

121

process2.wait()

122

```

123

124

### Command Building

125

126

Generate FFmpeg command-line arguments for debugging or manual execution.

127

128

```python { .api }

129

def get_args(stream_spec, overwrite_output: bool = False) -> list:

130

"""

131

Build command-line arguments for FFmpeg execution.

132

133

Parameters:

134

- stream_spec: Stream or stream specification

135

- overwrite_output: bool, add -y flag to overwrite files

136

137

Returns:

138

list: Command-line arguments (without 'ffmpeg' command)

139

"""

140

141

def compile(stream_spec, cmd: str = 'ffmpeg', overwrite_output: bool = False) -> list:

142

"""

143

Build complete command line for invoking FFmpeg.

144

145

Parameters:

146

- stream_spec: Stream or stream specification

147

- cmd: str/list, FFmpeg command (default: 'ffmpeg')

148

- overwrite_output: bool, add -y flag to overwrite files

149

150

Returns:

151

list: Complete command including FFmpeg executable

152

"""

153

```

154

155

**Usage Example:**

156

```python

157

# Build arguments for debugging

158

stream = ffmpeg.input('input.mp4').hflip().output('output.mp4')

159

args = ffmpeg.get_args(stream)

160

print(' '.join(args))

161

# Output: -i input.mp4 -filter_complex [0]hflip[s0] -map [s0] output.mp4

162

163

# Build complete command

164

cmd = ffmpeg.compile(stream, overwrite_output=True)

165

print(' '.join(cmd))

166

# Output: ffmpeg -i input.mp4 -filter_complex [0]hflip[s0] -map [s0] -y output.mp4

167

168

# Use custom FFmpeg path

169

custom_cmd = ffmpeg.compile(stream, cmd='/usr/local/bin/ffmpeg')

170

171

# Execute manually with subprocess

172

import subprocess

173

result = subprocess.run(custom_cmd, capture_output=True)

174

```

175

176

## Error Handling

177

178

```python { .api }

179

class Error(Exception):

180

"""

181

Exception raised when FFmpeg returns non-zero exit code.

182

183

Attributes:

184

- stdout: bytes, captured stdout data

185

- stderr: bytes, captured stderr data

186

"""

187

188

def __init__(self, cmd: str, stdout: bytes, stderr: bytes):

189

"""

190

Initialize error with command information.

191

192

Parameters:

193

- cmd: str, command that failed

194

- stdout: bytes, stdout data

195

- stderr: bytes, stderr data

196

"""

197

```

198

199

**Error Handling Patterns:**

200

```python

201

try:

202

ffmpeg.run(stream)

203

except ffmpeg.Error as e:

204

print(f"FFmpeg failed with error: {e}")

205

206

# Decode error messages

207

if e.stderr:

208

error_msg = e.stderr.decode('utf-8')

209

print(f"Error details: {error_msg}")

210

211

# Check for specific error conditions

212

if b'No such file or directory' in e.stderr:

213

print("Input file not found")

214

elif b'Invalid data found' in e.stderr:

215

print("Corrupt or invalid input file")

216

elif b'Permission denied' in e.stderr:

217

print("Insufficient permissions")

218

```

219

220

## Advanced Execution Patterns

221

222

### Progress Monitoring

223

224

```python

225

# Monitor progress with global args

226

stream = (

227

ffmpeg

228

.input('large_video.mp4')

229

.output('compressed.mp4', vcodec='libx264')

230

.global_args('-progress', 'progress.txt', '-nostats')

231

)

232

233

process = ffmpeg.run_async(stream)

234

235

# Read progress in real-time

236

import time

237

while process.poll() is None:

238

try:

239

with open('progress.txt', 'r') as f:

240

progress_data = f.read()

241

print(f"Progress: {progress_data}")

242

except FileNotFoundError:

243

pass

244

time.sleep(1)

245

```

246

247

### Resource Management

248

249

```python

250

import contextlib

251

252

@contextlib.contextmanager

253

def ffmpeg_process(stream_spec, **kwargs):

254

"""Context manager for FFmpeg processes."""

255

process = ffmpeg.run_async(stream_spec, **kwargs)

256

try:

257

yield process

258

finally:

259

if process.poll() is None: # Still running

260

process.terminate()

261

process.wait()

262

263

# Usage

264

with ffmpeg_process(stream, pipe_stdout=True) as process:

265

output_data = process.stdout.read()

266

# Process automatically terminated if exception occurs

267

```

268

269

### Batch Processing

270

271

```python

272

def process_videos(input_files, output_dir):

273

"""Process multiple videos in parallel."""

274

processes = []

275

276

for input_file in input_files:

277

output_file = f"{output_dir}/{input_file.stem}_processed.mp4"

278

stream = ffmpeg.input(str(input_file)).hflip().output(str(output_file))

279

process = ffmpeg.run_async(stream)

280

processes.append((process, input_file))

281

282

# Wait for all to complete

283

for process, input_file in processes:

284

try:

285

process.wait()

286

print(f"Completed: {input_file}")

287

except Exception as e:

288

print(f"Failed: {input_file} - {e}")

289

```