Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
105 lines (88 loc) · 3.13 KB

File metadata and controls

105 lines (88 loc) · 3.13 KB
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* Full Software Transcode Example
*
* This example demonstrates:
* - Software decoding (CPU)
* - Software encoding (CPU)
* - Maximum compatibility and control
*
* Use case: When you need maximum compatibility, specific codec features,
* or when hardware acceleration is not available
*
* Usage: tsx api-sw-transcode.ts <input> <output>
* Example: tsx examples/api-sw-transcode.ts testdata/video.mp4 examples/.tmp/api-sw-transcode.mp4
*/
import { Decoder, Demuxer, Encoder, FF_ENCODER_LIBX264, Muxer } from '../src/index.js';
const inputFile = process.argv[2];
const outputFile = process.argv[3];
if (!inputFile || !outputFile) {
console.log('Usage: tsx api-sw-transcode.ts <input> <output>');
console.log('Example: tsx api-sw-transcode.ts input.mp4 output.mp4');
process.exit(1);
}
console.log(`Input: ${inputFile}`);
console.log(`Output: ${outputFile}`);
// Open input file
await using input = await Demuxer.open(inputFile);
const videoStream = input.video();
const audioStream = input.audio();
if (!videoStream) {
throw new Error('No video stream found in input file');
}
console.log('Input Information:');
console.log(`Format: ${input.formatLongName}`);
console.log(`Duration: ${input.duration.toFixed(2)} seconds`);
console.log(`Video: ${videoStream.codecpar.width}x${videoStream.codecpar.height}`);
if (audioStream) {
console.log(`Audio: ${audioStream.codecpar.sampleRate}Hz, ${audioStream.codecpar.channels} channels`);
}
// Create software decoder (CPU)
console.log('Setting up software decoder...');
const decoder = await Decoder.create(videoStream);
// Create software encoder (CPU)
console.log('Setting up software encoder...');
const encoder = await Encoder.create(FF_ENCODER_LIBX264, {
decoder,
bitrate: '2M',
gopSize: 60,
options: {
preset: 'medium',
crf: 23,
profile: 'high',
level: '4.1',
},
});
// Create output using Muxer
await using output = await Muxer.open(outputFile);
const outputStreamIndex = output.addStream(encoder);
// Process video
console.log('🎥 Processing video...');
console.log(' Pure software pipeline: CPU decode → CPU encode');
console.log('');
let frameCount = 0;
let packetCount = 0;
const startTime = Date.now();
for await (using packet of input.packets(videoStream.index)) {
// Software decode → Software encode
for await (using frame of decoder.frames(packet)) {
if (frame) frameCount++;
// Software encode (null passes through to flush encoder)
for await (using encodedPacket of encoder.packets(frame)) {
await output.writePacket(encodedPacket, outputStreamIndex);
if (encodedPacket) packetCount++;
}
// Progress indicator
if (frameCount % 30 === 0) {
const elapsed = (Date.now() - startTime) / 1000;
const fps = frameCount / elapsed;
console.log(`Processed ${frameCount} frames @ ${fps.toFixed(1)} fps`);
}
}
}
const elapsed = (Date.now() - startTime) / 1000;
const avgFps = frameCount / elapsed;
console.log('Done!');
console.log(`Frames processed: ${frameCount}`);
console.log(`Packets written: ${packetCount}`);
console.log(`Time: ${elapsed.toFixed(2)} seconds`);
console.log(`Average FPS: ${avgFps.toFixed(1)}`);
Morty Proxy This is a proxified and sanitized view of the page, visit original site.