Commit Diff
Commit:
bf19b03e6400fa3a7573b0ba4fd057767f0adc22
From:
Omar Polo <op@omarpolo.com>
Date:
Mon May 9 16:56:50 2022 UTC
Message:
add a simple filetype detector instead of relying on file extension just a bit of "magic" :) Flac are easy, they always start with "fLaC". mp3 are weird because they either start with "ID3" (but this theoretically only ensures that's a tagged file, not an mp3) or 0xFF 0xFB. Ogg Opus should have a magic sequence "OpusHead" somewhere near the start of the file but also have the ogg' "OggS" magic bytes. I hope it's enough to distinguish between Ogg Opus and Vorbis. Another option would be to refactor play_oggvorbis/opus to not close the file on failure and try in cascade the play_* functions, but it's more complex and this solution seems to be enough.
commit - 184600a89b139d44c106a366c351bee471185137
commit + bf19b03e6400fa3a7573b0ba4fd057767f0adc22
blob - 61834acffd9976fb86f0c0e41dd7624eaa494618
blob + 8a11967a55fb6e34c043591ae23d80109c613d8c
--- player.c
+++ player.c
@@ -199,22 +199,38 @@ player_playnext(void)
int
player_playnext(void)
{
+ static char buf[512];
+ ssize_t r;
int fd = nextfd;
assert(nextfd != -1);
nextfd = -1;
- /* XXX: use magic(5) for this, not file extensions */
- if (strstr(nextpath, ".ogg") != NULL)
- return play_oggvorbis(fd);
- else if (strstr(nextpath, ".mp3") != NULL)
- return play_mp3(fd);
- else if (strstr(nextpath, ".flac") != NULL)
- return play_flac(fd);
- else if (strstr(nextpath, ".opus") != NULL)
+ r = read(fd, buf, sizeof(buf));
+
+ /* 8 byte is the larger magic number */
+ if (r < 8) {
+ log_warn("failed to read %s", nextpath);
+ goto err;
+ }
+
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ log_warn("lseek failed");
+ goto err;
+ }
+
+ if (memcmp(buf, "fLaC", 4) == 0)
+ return play_flac(fd);
+ if (memcmp(buf, "ID3", 3) == 0 ||
+ memcmp(buf, "\xFF\xFB", 2) == 0)
+ return play_mp3(fd);
+ if (memmem(buf, r, "OpusHead", 8) != NULL)
return play_opus(fd);
+ if (memmem(buf, r, "OggS", 4) != NULL)
+ return play_oggvorbis(fd);
log_warnx("unknown file type for %s", nextpath);
+err:
close(fd);
return -1;
}
Omar Polo