diff --git a/src/flac/Makefile b/src/flac/Makefile
index fb53a2bb2..28321384f 100644
--- a/src/flac/Makefile
+++ b/src/flac/Makefile
@@ -14,4 +14,4 @@ LD = ${CXX}
 
 CFLAGS += ${PLUGIN_CFLAGS}
 CPPFLAGS += ${PLUGIN_CPPFLAGS} ${LIBFLAC_CFLAGS} -I../..
-LIBS += ${LIBFLAC_LIBS}
+LIBS += ${LIBFLAC_LIBS} -laudtag -lm
diff --git a/src/flac/metadata.cc b/src/flac/metadata.cc
index f3b811203..5395ae636 100644
--- a/src/flac/metadata.cc
+++ b/src/flac/metadata.cc
@@ -143,8 +143,17 @@ bool FLACng::write_tuple(const char *filename, VFSFile &file, const Tuple &tuple
 
     chain = FLAC__metadata_chain_new();
 
-    if (!FLAC__metadata_chain_read_with_callbacks(chain, &file, io_callbacks))
-        goto ERR;
+    String mime = file.get_metadata("content-type");
+    if (FLAC_API_SUPPORTS_OGG_FLAC && mime && strstr(mime, "ogg"))
+    {
+        AUDERR("Tags in OGG/FLAC streams are currently readonly!");
+        goto ERR_RETURN;
+    }
+    else
+    {
+        if (! FLAC__metadata_chain_read_with_callbacks(chain, &file, io_callbacks))
+            goto ERR;
+    }
 
     iter = FLAC__metadata_iterator_new();
 
@@ -275,8 +284,17 @@ bool FLACng::read_tag (const char * filename, VFSFile & file, Tuple & tuple, Ind
 
     chain = FLAC__metadata_chain_new();
 
-    if (!FLAC__metadata_chain_read_with_callbacks(chain, &file, io_callbacks))
-        goto ERR;
+    String mime = file.get_metadata("content-type");
+    if (FLAC_API_SUPPORTS_OGG_FLAC && mime && strstr(mime, "ogg"))
+    {
+        if (! FLAC__metadata_chain_read_ogg_with_callbacks(chain, &file, io_callbacks))
+            goto ERR;
+    }
+    else
+    {
+        if (! FLAC__metadata_chain_read_with_callbacks(chain, &file, io_callbacks))
+            goto ERR;
+    }
 
     iter = FLAC__metadata_iterator_new();
 
diff --git a/src/flac/plugin.cc b/src/flac/plugin.cc
index d580f1450..ea960584d 100644
--- a/src/flac/plugin.cc
+++ b/src/flac/plugin.cc
@@ -21,12 +21,13 @@
 #include <string.h>
 
 #include <libaudcore/runtime.h>
+#include <audacious/audtag.h>
 
 #include "flacng.h"
 
 EXPORT FLACng aud_plugin_instance;
 
-static FLAC__StreamDecoder *decoder;
+static FLAC__StreamDecoder *decoder, *ogg_decoder;
 static callback_info *cinfo;
 
 bool FLACng::init()
@@ -60,12 +61,29 @@ bool FLACng::init()
         return false;
     }
 
+    if (FLAC_API_SUPPORTS_OGG_FLAC && ((ogg_decoder = FLAC__stream_decoder_new()) == nullptr
+            || FLAC__stream_decoder_init_ogg_stream(
+        ogg_decoder,
+        read_callback,
+        seek_callback,
+        tell_callback,
+        length_callback,
+        eof_callback,
+        write_callback,
+        metadata_callback,
+        error_callback,
+        cinfo)))
+    {
+        AUDWARN("Could not initialize the extra OGG FLAC decoder:  so no playing OGG-FLAC streams!\n");
+    }
+
     AUDDBG("Plugin initialized.\n");
     return true;
 }
 
 void FLACng::cleanup()
 {
+    if (ogg_decoder)  FLAC__stream_decoder_delete(ogg_decoder);
     FLAC__stream_decoder_delete(decoder);
     delete cinfo;
 }
@@ -115,10 +133,25 @@ bool FLACng::play(const char *filename, VFSFile &file)
 {
     Index<char> play_buffer;
     bool error = false;
+    bool stream = (file.fsize() < 0);
+    Tuple tuple;
+    if (stream)
+    {
+        tuple = get_playback_tuple();
+        if (audtag::read_tag(file, tuple, nullptr))
+            set_playback_tuple(tuple.ref());
+    }
 
     cinfo->fd = &file;
 
-    if (read_metadata(decoder, cinfo) == false)
+    FLAC__StreamDecoder *which_decoder = decoder;
+    if (FLAC_API_SUPPORTS_OGG_FLAC && ogg_decoder)
+    {
+        String mime = file.get_metadata("content-type");
+        if (mime && strstr(mime, "ogg"))  which_decoder = ogg_decoder;
+    }
+
+    if (read_metadata(which_decoder, cinfo) == false)
     {
         AUDERR("Could not prepare file for playing!\n");
         error = true;
@@ -128,20 +161,24 @@ bool FLACng::play(const char *filename, VFSFile &file)
     play_buffer.resize(BUFFER_SIZE_BYTE);
 
     set_stream_bitrate(cinfo->bitrate);
+
+    if (stream && tuple.fetch_stream_info(file))
+        set_playback_tuple(tuple.ref());
+
     open_audio(SAMPLE_FMT(cinfo->bits_per_sample), cinfo->sample_rate, cinfo->channels);
 
-    while (FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_END_OF_STREAM)
+    while (FLAC__stream_decoder_get_state(which_decoder) != FLAC__STREAM_DECODER_END_OF_STREAM)
     {
         if (check_stop ())
             break;
 
         int seek_value = check_seek ();
         if (seek_value >= 0)
-            FLAC__stream_decoder_seek_absolute (decoder, (int64_t)
+            FLAC__stream_decoder_seek_absolute(which_decoder, (int64_t)
              seek_value * cinfo->sample_rate / 1000);
 
         /* Try to decode a single frame of audio */
-        if (FLAC__stream_decoder_process_single(decoder) == false)
+        if (FLAC__stream_decoder_process_single(which_decoder) == false)
         {
             AUDERR("Error while decoding!\n");
             error = true;
@@ -159,7 +196,7 @@ bool FLACng::play(const char *filename, VFSFile &file)
 ERR_NO_CLOSE:
     cinfo->reset();
 
-    if (FLAC__stream_decoder_flush(decoder) == false)
+    if (FLAC__stream_decoder_flush(which_decoder) == false)
         AUDERR("Could not flush decoder state!\n");
 
     return ! error;
@@ -172,4 +209,4 @@ const char FLACng::about[] =
 
 const char *const FLACng::exts[] = { "flac", "fla", nullptr };
 
-const char *const FLACng::mimes[] = { "audio/flac", "audio/x-flac", nullptr };
+const char *const FLACng::mimes[] = { "audio/flac", "audio/x-flac", "audio/ogg", "application/ogg", nullptr };
