Skip to content

Commit 1079b56

Browse files
committed
Add playback support and multi-format probing
Extend the default engine to support probing for wav, png, jpeg, and mp4/m4a formats. Introduce strict validation to allow handling of additional media types without relying solely on file extensions. Add a new get(Path) alias for probe(Path) to simplify access patterns. Introduce playback APIs with dry-run behavior and optional desktop-open backend support. Replace direct stub conversion logic with conversion hub routing. Add explicit unsupported-route errors and include a temporary wav<->pcm stub path. Update facade and fixture-based tests to cover probing, validation, playback, and conversion route behavior. Refresh README documentation to reflect updated features and current limitations. BREAKING CHANGE: CodecMediaEngine now requires implementations for get(Path) and play(Path, PlaybackOptions) in custom engines.
1 parent eaae985 commit 1079b56

26 files changed

+1322
-36
lines changed

README.md

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,43 @@
11
# CodecMedia
22

3-
CodecMedia is a Java library for media probing, validation, metadata sidecar persistence, audio extraction, and file conversion workflows.
3+
CodecMedia is a Java library for media probing, validation, metadata sidecar persistence, audio extraction, playback workflow simulation, and conversion routing.
4+
5+
<p align="center">
6+
<img src="https://www.tamkungz.me/assets-image/CodecMedia_Full_Logo.png" width="70%" alt="CodecMedia Logo">
7+
</p>
48

59
## Features
610

7-
- Media probing facade via `CodecMedia.createDefault()`
8-
- MP3 frame parsing support
9-
- OGG/Vorbis page parsing support
10-
- Validation with size limits and strict parser checks for MP3/OGG
11+
- Media engine facade via `CodecMedia.createDefault()`
12+
- Probing support for:
13+
- MP3
14+
- OGG/Vorbis
15+
- WAV (RIFF/WAVE)
16+
- PNG
17+
- JPEG
18+
- MP4 (basic ISO BMFF parsing)
19+
- Validation with size limits and strict parser checks for MP3/OGG/WAV/PNG/JPEG/MP4
1120
- Metadata read/write with sidecar persistence (`.codecmedia.properties`)
12-
- In-Java audio extraction and conversion file operations (no external tools required)
21+
- In-Java extraction and conversion file operations (no external transcoder required for current stub flows)
22+
- Playback API with dry-run support and optional desktop-open backend
23+
- Conversion hub routing with explicit unsupported routes and a stub `wav <-> pcm` path
1324

1425
## API Behavior Summary
1526

16-
- `probe(input)`: detects media/container characteristics and stream info for supported formats.
17-
- `readMetadata(input)`: returns derived probe metadata plus sidecar metadata entries when present.
27+
- `get(input)`: alias of `probe(input)` for convenience.
28+
- `probe(input)`: detects media/container characteristics and returns technical stream info for supported formats.
29+
- `readMetadata(input)`: returns derived probe metadata plus sidecar entries when present.
1830
- `writeMetadata(input, metadata)`: validates and writes metadata to a sidecar properties file next to the input.
1931
- `extractAudio(input, outputDir, options)`: validates audio input and writes extracted output into `outputDir`.
20-
- `convert(input, output, options)`: writes conversion output and enforces `overwrite` behavior.
21-
- `validate(input, options)`: validates existence, max size, and optionally strict parser-level checks.
32+
- `convert(input, output, options)`: performs routed conversion behavior and enforces `overwrite` handling.
33+
- `play(input, options)`: supports dry-run playback and optional system default app launch.
34+
- `validate(input, options)`: validates existence, max size, and optional strict parser-level checks.
35+
36+
## Notes and Limitations
37+
38+
- Current probing focuses on **technical media info** (mime/type/streams/basic tags).
39+
- `readMetadata` currently uses sidecar metadata persistence; it is **not** a full embedded tag extractor (for example ID3 album art/APIC).
40+
- Current audio-to-audio conversion is mostly unsupported except a temporary stub copy route for `wav <-> pcm`.
2241

2342
## Requirements
2443

@@ -31,21 +50,29 @@ CodecMedia is a Java library for media probing, validation, metadata sidecar per
3150
mvn clean test
3251
```
3352

34-
## Play/Probe Fixture Test
53+
## Fixture-Driven Tests
3554

36-
The repository includes a fixture-driven test that probes real audio files under `src/test/resources`:
55+
Fixtures are in `src/test/resources`, including:
3756

3857
- `c-major-scale_test_ableton-live.wav`
3958
- `c-major-scale_test_audacity.mp3`
4059
- `c-major-scale_test_ffmpeg.ogg`
4160
- `c-major-scale_test_web-convert_mono.mp3`
61+
- `mp4_test.mp4`
62+
- `png_test.png`
4263

43-
Run only this test:
64+
Run probe fixture test only:
4465

4566
```bash
4667
mvn -Dtest=CodecMediaPlayTest test
4768
```
4869

70+
Run facade-focused tests only:
71+
72+
```bash
73+
mvn -Dtest=CodecMediaFacadeTest test
74+
```
75+
4976
## Full Test Suite
5077

5178
```bash

src/main/java/me/tamkungz/codecmedia/CodecMediaEngine.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,102 @@
44
import me.tamkungz.codecmedia.model.ConversionResult;
55
import me.tamkungz.codecmedia.model.ExtractionResult;
66
import me.tamkungz.codecmedia.model.Metadata;
7+
import me.tamkungz.codecmedia.model.PlaybackResult;
78
import me.tamkungz.codecmedia.model.ProbeResult;
89
import me.tamkungz.codecmedia.model.ValidationResult;
910
import me.tamkungz.codecmedia.options.AudioExtractOptions;
1011
import me.tamkungz.codecmedia.options.ConversionOptions;
12+
import me.tamkungz.codecmedia.options.PlaybackOptions;
1113
import me.tamkungz.codecmedia.options.ValidationOptions;
1214

15+
/**
16+
* Core media engine contract used by {@link CodecMedia}.
17+
* <p>
18+
* The current default implementation focuses on practical probing/validation workflows and
19+
* light-weight conversion routing. For richer embedded metadata (for example MP3 album cover/APIC),
20+
* callers should treat {@link #probe(Path)} output as technical media info rather than full tag extraction.
21+
*/
1322
public interface CodecMediaEngine {
1423

24+
/**
25+
* Convenience alias of {@link #probe(Path)}.
26+
*
27+
* @param input media file path
28+
* @return probe result describing detected media characteristics
29+
* @throws CodecMediaException when probing fails
30+
*/
31+
ProbeResult get(Path input) throws CodecMediaException;
32+
33+
/**
34+
* Detects media format and returns technical stream/container information.
35+
*
36+
* @param input media file path
37+
* @return probe result containing mime, extension, media type, streams, and basic tags
38+
* @throws CodecMediaException when the file is missing or parsing fails
39+
*/
1540
ProbeResult probe(Path input) throws CodecMediaException;
1641

42+
/**
43+
* Reads metadata associated with the file.
44+
* <p>
45+
* In the default stub implementation this reads sidecar metadata plus base probe fields,
46+
* not full embedded tag catalogs for every format.
47+
*
48+
* @param input media file path
49+
* @return metadata entries
50+
* @throws CodecMediaException when reading fails
51+
*/
1752
Metadata readMetadata(Path input) throws CodecMediaException;
1853

54+
/**
55+
* Writes metadata associated with the file.
56+
* <p>
57+
* In the default stub implementation this writes a sidecar properties file.
58+
*
59+
* @param input media file path
60+
* @param metadata metadata entries to persist
61+
* @throws CodecMediaException when validation or writing fails
62+
*/
1963
void writeMetadata(Path input, Metadata metadata) throws CodecMediaException;
2064

65+
/**
66+
* Extracts audio from an input media file into the given output directory.
67+
*
68+
* @param input source media file
69+
* @param outputDir target directory for extracted output
70+
* @param options extraction options; implementation defaults may be used when {@code null}
71+
* @return extraction result describing output file and format
72+
* @throws CodecMediaException when extraction is unsupported or fails
73+
*/
2174
ExtractionResult extractAudio(Path input, Path outputDir, AudioExtractOptions options) throws CodecMediaException;
2275

76+
/**
77+
* Converts media according to the requested options.
78+
*
79+
* @param input source media file
80+
* @param output output media file path
81+
* @param options conversion options; implementation defaults may be used when {@code null}
82+
* @return conversion result
83+
* @throws CodecMediaException when route is unsupported or conversion fails
84+
*/
2385
ConversionResult convert(Path input, Path output, ConversionOptions options) throws CodecMediaException;
2486

87+
/**
88+
* Starts playback/viewing for supported media.
89+
*
90+
* @param input source media file
91+
* @param options playback options controlling dry-run and external app behavior
92+
* @return playback result including backend and started status
93+
* @throws CodecMediaException when playback cannot be started
94+
*/
95+
PlaybackResult play(Path input, PlaybackOptions options) throws CodecMediaException;
96+
97+
/**
98+
* Validates file existence and optional strict format constraints.
99+
*
100+
* @param input media file path
101+
* @param options validation options; implementation defaults may be used when {@code null}
102+
* @return validation result with warnings/errors
103+
*/
25104
ValidationResult validate(Path input, ValidationOptions options) throws CodecMediaException;
26105
}

0 commit comments

Comments
 (0)