@@ -98,14 +98,13 @@ export const ffmpegCompressVideo = task({
98
98
99
99
// Read the compressed video
100
100
const compressedVideo = await fs .readFile (outputPath );
101
-
102
101
const compressedSize = compressedVideo .length ;
103
102
104
103
// Log compression results
105
104
logger .log (` Compressed video size: ${compressedSize } bytes ` );
106
- logger .log (` Compressed video saved at: ${ outputPath } ` );
105
+ logger .log (` Temporary compressed video file created ` , { outputPath } );
107
106
108
- // Upload the compressed video to S3, replacing slashes with underscores
107
+ // Create the r2Key for the extracted audio, using the base name of the output path
109
108
const r2Key = ` processed-videos/${path .basename (outputPath )} ` ;
110
109
111
110
const uploadParams = {
@@ -116,22 +115,31 @@ export const ffmpegCompressVideo = task({
116
115
117
116
// Upload the video to R2 and get the URL
118
117
await s3Client .send (new PutObjectCommand (uploadParams ));
119
- const r2Url = ` https://${process .env .R2_ACCOUNT_ID }.r2.cloudflarestorage.com/${process .env .R2_BUCKET }/${r2Key } ` ;
120
- logger .log (" Compressed video uploaded to R2" , { url: r2Url });
118
+ logger .log (` Compressed video saved to your r2 bucket ` , { r2Key });
121
119
122
120
// Delete the temporary compressed video file
123
121
await fs .unlink (outputPath );
122
+ logger .log (` Temporary compressed video file deleted ` , { outputPath });
124
123
125
- // Return the compressed video file path, compressed size, and S3 URL
124
+ // Return the compressed video buffer and r2 key
126
125
return {
127
- compressedVideoPath: outputPath ,
128
- compressedSize ,
129
- r2Url ,
126
+ Bucket: process .env .R2_BUCKET ,
127
+ r2Key ,
130
128
};
131
129
},
132
130
});
133
131
```
134
132
133
+ ### Testing:
134
+
135
+ To test this task, use this payload structure:
136
+
137
+ ``` json
138
+ {
139
+ "videoUrl" : " <video-url>"
140
+ }
141
+ ```
142
+
135
143
## Extract audio from a video using FFmpeg
136
144
137
145
This task demonstrates how to use FFmpeg to extract audio from a video, convert it to WAV format, and upload it to R2 storage.
@@ -145,11 +153,6 @@ This task demonstrates how to use FFmpeg to extract audio from a video, convert
145
153
146
154
### Task code
147
155
148
- <Warning >
149
- When testing, make sure to provide a video URL that contains audio. If the video does not have
150
- audio, the task will fail.
151
- </Warning >
152
-
153
156
``` ts trigger/ffmpeg-extract-audio.ts
154
157
import { PutObjectCommand , S3Client } from " @aws-sdk/client-s3" ;
155
158
import { logger , task } from " @trigger.dev/sdk/v3" ;
@@ -176,63 +179,81 @@ export const ffmpegExtractAudio = task({
176
179
run : async (payload : { videoUrl: string }) => {
177
180
const { videoUrl } = payload ;
178
181
179
- // Generate temporary and output file names
182
+ // Generate temporary file names
180
183
const tempDirectory = os .tmpdir ();
181
- const outputPath = path .join (tempDirectory , ` output_ ${Date .now ()}.wav` );
184
+ const outputPath = path .join (tempDirectory , ` audio_ ${Date .now ()}.wav` );
182
185
183
186
// Fetch the video
184
187
const response = await fetch (videoUrl );
185
188
186
- // Convert the video to WAV
189
+ // Extract the audio
187
190
await new Promise ((resolve , reject ) => {
188
191
if (! response .body ) {
189
192
return reject (new Error (" Failed to fetch video" ));
190
193
}
194
+
191
195
ffmpeg (Readable .from (response .body ))
192
- .toFormat (" wav" )
193
- .save (outputPath )
194
- .on (" end" , () => {
195
- logger .log (` WAV file saved to ${outputPath } ` );
196
- resolve (outputPath );
197
- })
198
- .on (" error" , (err ) => {
199
- reject (err );
200
- });
196
+ .outputOptions ([
197
+ " -vn" , // Disable video output
198
+ " -acodec pcm_s16le" , // Use PCM 16-bit little-endian encoding
199
+ " -ar 44100" , // Set audio sample rate to 44.1 kHz
200
+ " -ac 2" , // Set audio channels to stereo
201
+ ])
202
+ .output (outputPath )
203
+ .on (" end" , resolve )
204
+ .on (" error" , reject )
205
+ .run ();
201
206
});
202
207
203
- // Read the WAV file
204
- const wavBuffer = await fs .readFile (outputPath );
208
+ // Read the extracted audio
209
+ const audioBuffer = await fs .readFile (outputPath );
210
+ const audioSize = audioBuffer .length ;
205
211
206
- // Log the output file path
207
- logger .log (` Converted video saved at: ${outputPath } ` );
212
+ // Log audio extraction results
213
+ logger .log (` Extracted audio size: ${audioSize } bytes ` );
214
+ logger .log (` Temporary audio file created ` , { outputPath });
208
215
209
- // Upload the compressed video to S3, replacing slashes with underscores
210
- const r2Key = ` processed -audio/${path .basename (outputPath )}` ;
216
+ // Create the r2Key for the extracted audio, using the base name of the output path
217
+ const r2Key = ` extracted -audio/${path .basename (outputPath )}` ;
211
218
212
219
const uploadParams = {
213
220
Bucket: process .env .R2_BUCKET ,
214
221
Key: r2Key ,
215
- Body: wavBuffer ,
222
+ Body: audioBuffer ,
216
223
};
217
224
218
225
// Upload the audio to R2 and get the URL
219
226
await s3Client .send (new PutObjectCommand (uploadParams ));
220
- const r2Url = ` https://${process .env .R2_ACCOUNT_ID }.r2.cloudflarestorage.com/${process .env .R2_BUCKET }/${r2Key } ` ;
221
- logger .log (" Extracted audio uploaded to R2" , { url: r2Url });
227
+ logger .log (` Extracted audio saved to your R2 bucket ` , { r2Key });
222
228
223
- // Delete the temporary file
229
+ // Delete the temporary audio file
224
230
await fs .unlink (outputPath );
231
+ logger .log (` Temporary audio file deleted ` , { outputPath });
225
232
226
- // Return the WAV buffer and file path
233
+ // Return the audio file path, size, and R2 URL
227
234
return {
228
- wavBuffer ,
229
- wavFilePath: outputPath ,
230
- r2Url ,
235
+ Bucket: process .env .R2_BUCKET ,
236
+ r2Key ,
231
237
};
232
238
},
233
239
});
234
240
```
235
241
242
+ ### Testing:
243
+
244
+ To test this task, use this payload structure:
245
+
246
+ <Warning >
247
+ Make sure to provide a video URL that contains audio. If the video does not have audio, the task
248
+ will fail.
249
+ </Warning >
250
+
251
+ ``` json
252
+ {
253
+ "videoUrl" : " <video-url>"
254
+ }
255
+ ```
256
+
236
257
## Generate a thumbnail from a video using FFmpeg
237
258
238
259
This task demonstrates how to use FFmpeg to generate a thumbnail from a video at a specific time and upload the generated thumbnail to R2 storage.
@@ -298,7 +319,7 @@ export const ffmpegGenerateThumbnail = task({
298
319
// Read the generated thumbnail
299
320
const thumbnail = await fs .readFile (outputPath );
300
321
301
- // Upload the compressed video to S3, replacing slashes with underscores
322
+ // Create the r2Key for the extracted audio, using the base name of the output path
302
323
const r2Key = ` thumbnails/${path .basename (outputPath )} ` ;
303
324
304
325
const uploadParams = {
@@ -318,7 +339,7 @@ export const ffmpegGenerateThumbnail = task({
318
339
// Log thumbnail generation results
319
340
logger .log (` Thumbnail uploaded to S3: ${r2Url } ` );
320
341
321
- // Return the thumbnail buffer, file path, sizes, and S3 URL
342
+ // Return the thumbnail buffer, path, and R2 URL
322
343
return {
323
344
thumbnailBuffer: thumbnail ,
324
345
thumbnailPath: outputPath ,
@@ -327,3 +348,13 @@ export const ffmpegGenerateThumbnail = task({
327
348
},
328
349
});
329
350
```
351
+
352
+ ## Testing your task
353
+
354
+ To test this task in the dashboard, you can use the following payload:
355
+
356
+ ``` json
357
+ {
358
+ "videoUrl" : " <video-url>"
359
+ }
360
+ ```
0 commit comments