diff --git a/.gitignore b/.gitignore index 232a892..ed57edc 100644 --- a/.gitignore +++ b/.gitignore @@ -63,6 +63,10 @@ example_*.i2m *.test.js *.spec.js +# Example generated files +examples/risitas_with_chiquito.i2m +examples/extracted_* + # Build directories dist/ build/ \ No newline at end of file diff --git a/README.md b/README.md index 9bee586..c90e216 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,24 @@ npm install -g img2mp3 npm install img2mp3 ``` +## Quick Start + +To see IMG2MP3 in action, run the included example: + +```bash +# Clone the repository +git clone https://github.com/ale/img2mp3.git +cd img2mp3 + +# Install dependencies +npm install + +# Run the example with sample files +npm run example +``` + +This will demonstrate encoding, decoding, and playing with the included sample files (`risitas.jpg` and `chiquito-cobarde.mp3`). + ## Usage ### Command Line Interface diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..fa1e742 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,50 @@ +# Examples + +This directory contains example files and usage demonstrations for IMG2MP3. + +## Files + +- `basic_usage.js` - Complete example showing all functionality +- `risitas.jpg` - Sample image file for testing +- `chiquito-cobarde.mp3` - Sample audio file for testing + +## Running the Example + +To run the complete example with the provided files: + +```bash +# From the project root directory +npm run example + +# Or run directly +node examples/basic_usage.js +``` + +## What the Example Does + +1. **Encodes** the MP3 file into the image, creating a `.i2m` file +2. **Gets information** about the created `.i2m` file +3. **Plays** the embedded audio (if an audio player is available) +4. **Decodes** the `.i2m` file back to separate image and MP3 files + +## Expected Output + +The example will create the following files in the `examples` directory: + +- `risitas_with_chiquito.i2m` - The image with embedded audio +- `extracted_risitas.png` - The extracted original image +- `extracted_chiquito.mp3` - The extracted audio file + +## Testing Different Files + +You can replace `risitas.jpg` and `chiquito-cobarde.mp3` with your own files to test with different content. Just make sure to update the filenames in `basic_usage.js` accordingly. + +## Audio Players + +For the playback functionality to work, you need one of these audio players installed: + +- **Linux**: `sudo apt install mpg123` or `sudo apt install mpv` +- **macOS**: `brew install mpg123` or `brew install mpv` +- **Windows**: Install [mpv](https://mpv.io/installation/) + +If no audio player is available, the example will show a warning but continue with the other functionality. diff --git a/examples/basic_usage.js b/examples/basic_usage.js index f117886..476b304 100644 --- a/examples/basic_usage.js +++ b/examples/basic_usage.js @@ -7,48 +7,59 @@ async function example() { console.log('šŸŽµ IMG2MP3 Example Usage\n'); try { - // Note: You'll need to provide actual image and MP3 files - const imagePath = 'sample_image.jpg'; // Replace with actual image - const mp3Path = 'sample_audio.mp3'; // Replace with actual MP3 - const outputPath = 'example_output.i2m'; + // Using the actual files in the examples directory + const imagePath = path.join(__dirname, 'risitas.jpg'); + const mp3Path = path.join(__dirname, 'chiquito-cobarde.mp3'); + const outputPath = path.join(__dirname, 'risitas_with_chiquito.i2m'); console.log('1. Encoding MP3 into image...'); - // Uncomment when you have actual files: - // const encodeResult = await img2mp3.encode(imagePath, mp3Path, outputPath); - // console.log('āœ… Encoding successful!'); - // console.log(` Output size: ${encodeResult.outputSize} bytes`); - // console.log(` Container image: ${encodeResult.imageSize}\n`); + console.log(` Image: ${path.basename(imagePath)}`); + console.log(` Audio: ${path.basename(mp3Path)}`); + + const encodeResult = await img2mp3.encode(imagePath, mp3Path, outputPath); + console.log('āœ… Encoding successful!'); + console.log(` Original image: ${formatBytes(encodeResult.originalImageSize)}`); + console.log(` MP3 file: ${formatBytes(encodeResult.mp3Size)}`); + console.log(` Output size: ${formatBytes(encodeResult.outputSize)}`); + console.log(` Container image: ${encodeResult.imageSize}\n`); console.log('2. Getting file information...'); - // Uncomment when you have an actual .i2m file: - // const info = await img2mp3.getInfo(outputPath); - // if (info.isValid) { - // console.log('āœ… Valid .i2m file detected!'); - // console.log(` Embedded audio: ${info.mp3Size} bytes`); - // console.log(` Original image: ${info.originalImageSize} bytes\n`); - // } + const info = await img2mp3.getInfo(outputPath); + if (info.isValid) { + console.log('āœ… Valid .i2m file detected!'); + console.log(` Embedded audio: ${formatBytes(info.mp3Size)}`); + console.log(` Original image: ${formatBytes(info.originalImageSize)}`); + console.log(` Container dimensions: ${info.dimensions}\n`); + } console.log('3. Playing embedded audio...'); - // Uncomment when you have an actual .i2m file: - // await img2mp3.play(outputPath); - // console.log('āœ… Playback finished!\n'); + console.log(' (Press Ctrl+C to stop playback)'); + try { + await img2mp3.play(outputPath); + console.log('āœ… Playback finished!\n'); + } catch (playError) { + console.log(`āš ļø Playback failed: ${playError.message}`); + console.log(' (This is normal if no audio player is installed)\n'); + } console.log('4. Decoding back to separate files...'); - // Uncomment when you have an actual .i2m file: - // const decodeResult = await img2mp3.decode( - // outputPath, - // 'extracted_image.png', - // 'extracted_audio.mp3' - // ); - // console.log('āœ… Decoding successful!'); - // console.log(` Extracted image: ${decodeResult.extractedImageSize} bytes`); - // console.log(` Extracted audio: ${decodeResult.extractedMp3Size} bytes`); + const extractedImagePath = path.join(__dirname, 'extracted_risitas.png'); + const extractedMp3Path = path.join(__dirname, 'extracted_chiquito.mp3'); - console.log('\nšŸŽ‰ Example completed!'); - console.log('\nTo run this example with real files:'); - console.log('1. Place an image file named "sample_image.jpg" in this directory'); - console.log('2. Place an MP3 file named "sample_audio.mp3" in this directory'); - console.log('3. Uncomment the code above and run again'); + const decodeResult = await img2mp3.decode( + outputPath, + extractedImagePath, + extractedMp3Path + ); + console.log('āœ… Decoding successful!'); + console.log(` Extracted image: ${path.basename(extractedImagePath)} (${formatBytes(decodeResult.extractedImageSize)})`); + console.log(` Extracted audio: ${path.basename(extractedMp3Path)} (${formatBytes(decodeResult.extractedMp3Size)})`); + + console.log('\nšŸŽ‰ Example completed successfully!'); + console.log('\nGenerated files:'); + console.log(`šŸ“ ${path.basename(outputPath)} - The image with embedded audio`); + console.log(`šŸ–¼ļø ${path.basename(extractedImagePath)} - Extracted image`); + console.log(`šŸŽµ ${path.basename(extractedMp3Path)} - Extracted audio`); } catch (error) { console.error('āŒ Error:', error.message); @@ -58,5 +69,20 @@ async function example() { } } +/** + * Format bytes to human readable format + */ +function formatBytes(bytes, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; +} + // Run the example example().catch(console.error); diff --git a/examples/chiquito-cobarde.mp3 b/examples/chiquito-cobarde.mp3 new file mode 100644 index 0000000..1b395f0 Binary files /dev/null and b/examples/chiquito-cobarde.mp3 differ diff --git a/examples/risitas.jpg b/examples/risitas.jpg new file mode 100644 index 0000000..8c394f0 Binary files /dev/null and b/examples/risitas.jpg differ