diff --git a/lib/ts_packet.cpp b/lib/ts_packet.cpp
index e9b1899d..e3a650e7 100644
--- a/lib/ts_packet.cpp
+++ b/lib/ts_packet.cpp
@@ -527,9 +527,13 @@ namespace TS {
 /// \param len The length of this frame.
 /// \param PTS The timestamp of the frame.
   std::string & Packet::getPESVideoLeadIn(unsigned int len, unsigned long long PTS, unsigned long long offset, bool isAligned, uint64_t bps) {
-    len += (offset ? 13 : 8);
+    if (len){
+      len += (offset ? 13 : 8);
+    }
     if (bps >= 50){
-      len += 3;
+      if (len){
+        len += 3;
+      }
     }else{
       bps = 0;
     }
@@ -826,7 +830,7 @@ namespace TS {
       case 0x15: return "meta PES";
       case 0x16: return "meta section";
       case 0x1B: return "H264";
-      case 0x24: return "H265";
+      case 0x24: return "HEVC";
       case 0x81: return "AC3";
       default: return "unknown";
     }
@@ -1219,6 +1223,8 @@ namespace TS {
         entry.setStreamType(0x1B);
       }else if (myMeta.tracks[*it].codec == "HEVC"){
         entry.setStreamType(0x24);
+      }else if (myMeta.tracks[*it].codec == "MPEG2"){
+        entry.setStreamType(0x02);
       }else if (myMeta.tracks[*it].codec == "AAC"){
         entry.setStreamType(0x0F);
         std::string aac_info("\174\002\121\000", 4);//AAC descriptor: AAC Level 2. Hardcoded, because... what are AAC levels, anyway?
@@ -1229,7 +1235,7 @@ namespace TS {
           aac_info.append("\000", 1);
         }
         entry.setESInfo(aac_info);
-      }else if (myMeta.tracks[*it].codec == "MP3"){
+      }else if (myMeta.tracks[*it].codec == "MP3" || myMeta.tracks[*it].codec == "MP2"){
         entry.setStreamType(0x03);
       }else if (myMeta.tracks[*it].codec == "AC3"){
         entry.setStreamType(0x81);
diff --git a/lib/ts_stream.cpp b/lib/ts_stream.cpp
index bc729941..df1451bb 100644
--- a/lib/ts_stream.cpp
+++ b/lib/ts_stream.cpp
@@ -6,6 +6,8 @@
 #include "nal.h"
 #include <sys/stat.h>
 #include <stdint.h>
+#include "mpeg.h"
+
 
 namespace TS{
 
@@ -187,6 +189,8 @@ namespace TS{
         case H265:
         case AC3:
         case ID3:
+        case MP2:
+        case MPEG2:
           pidToCodec[pid] = sType;
           if (sType == ID3){
             metaInit[pid] = std::string(entry.getESInfo(), entry.getESInfoLength());
@@ -517,10 +521,13 @@ namespace TS{
         }
       }
     }
-    if (thisCodec == ID3 || thisCodec == AC3){
+    if (thisCodec == ID3 || thisCodec == AC3 || thisCodec == MP2){
       out.push_back(DTSC::Packet());
       out.back().genericFill(timeStamp, timeOffset, tid, pesPayload, realPayloadSize,
                                          bPos, 0);
+      if (thisCodec == MP2 && !mp2Hdr.count(tid)){
+        mp2Hdr[tid] = std::string(pesPayload, realPayloadSize);
+      }
 
     }
 
@@ -626,6 +633,37 @@ namespace TS{
         nextPtr = nalu::scanAnnexB(pesPayload, realPayloadSize);
       }
     }
+    if (thisCodec == MPEG2){
+      const char *origBegin = pesPayload;
+      size_t origSize = realPayloadSize;
+      const char *nextPtr;
+      const char *pesEnd = pesPayload+realPayloadSize;
+      uint32_t nalSize = 0;
+
+      bool isKeyFrame = false;
+
+      nextPtr = nalu::scanAnnexB(pesPayload, realPayloadSize);
+      if (!nextPtr){
+        WARN_MSG("No start code found in entire PES packet!");
+        return;
+      }
+
+      while (nextPtr < pesEnd){
+        if (!nextPtr){nextPtr = pesEnd;}
+        //Calculate size of NAL unit, removing null bytes from the end
+        nalSize = nalu::nalEndPosition(pesPayload, nextPtr - pesPayload) - pesPayload;
+
+        // Check if this is a keyframe
+        parseNal(tid, pesPayload, nextPtr, isKeyFrame);
+
+        if (((nextPtr - pesPayload) + 3) >= realPayloadSize){break;}//end of the loop
+        realPayloadSize -= ((nextPtr - pesPayload) + 3); // decrease the total size
+        pesPayload = nextPtr + 3;
+        nextPtr = nalu::scanAnnexB(pesPayload, realPayloadSize);
+      }
+      out.push_back(DTSC::Packet());
+      out.back().genericFill(timeStamp, timeOffset, tid, origBegin, origSize, bPos, isKeyFrame);
+    }
   }
 
   void Stream::getPacket(unsigned long tid, DTSC::Packet &pack){
@@ -660,11 +698,27 @@ namespace TS{
     bool firstSlice = true;
     char typeNal;
 
-    isKeyFrame = false;
     if (pidToCodec[tid] == MPEG2){
+      typeNal = pesPayload[0];
+      switch (typeNal){
+        case 0xB3:
+          if (!mpeg2SeqHdr.count(tid)){
+            mpeg2SeqHdr[tid] = std::string(pesPayload, (nextPtr - pesPayload));
+          }
+          break;
+        case 0xB5:
+          if (!mpeg2SeqExt.count(tid)){
+            mpeg2SeqExt[tid] = std::string(pesPayload, (nextPtr - pesPayload));
+          }
+          break;
+        case 0xB8:
+          isKeyFrame = true;
+          break;
+      }
       return;
     }
 
+    isKeyFrame = false;
     if (pidToCodec[tid] == H264){
       typeNal = pesPayload[0] & 0x1F;
       switch (typeNal){
@@ -816,6 +870,17 @@ namespace TS{
           }
         }
       }break;
+      case MPEG2:{
+        meta.tracks[mId].type = "video";
+        meta.tracks[mId].codec = "MPEG2";
+        meta.tracks[mId].trackID = mId;
+        meta.tracks[mId].init = std::string("\000\000\001", 3) + mpeg2SeqHdr[it->first] + std::string("\000\000\001", 3) + mpeg2SeqExt[it->first];
+
+        Mpeg::MPEG2Info info = Mpeg::parseMPEG2Header(meta.tracks[mId].init);
+        meta.tracks[mId].width = info.width;
+        meta.tracks[mId].height = info.height;
+        meta.tracks[mId].fpks = info.fps * 1000;
+      }break;
       case ID3:{
         meta.tracks[mId].type = "meta";
         meta.tracks[mId].codec = "ID3";
@@ -831,6 +896,18 @@ namespace TS{
         meta.tracks[mId].rate = 0;
         meta.tracks[mId].channels = 0;
       }break;
+      case MP2:{
+        meta.tracks[mId].type = "audio";
+        meta.tracks[mId].codec = "MP2";
+        meta.tracks[mId].trackID = mId;
+
+        Mpeg::MP2Info info = Mpeg::parseMP2Header(mp2Hdr[it->first]);
+        meta.tracks[mId].rate = info.sampleRate;
+        meta.tracks[mId].channels = info.channels;
+
+        ///\todo Fix this value
+        meta.tracks[mId].size = 0;
+      }break;
       case AAC:{
         meta.tracks[mId].type = "audio";
         meta.tracks[mId].codec = "AAC";
@@ -887,7 +964,10 @@ namespace TS{
             case AAC:
             case H265:
             case AC3:
-            case ID3: result.insert(entry.getElementaryPid()); break;
+            case ID3:
+            case MP2:
+            case MPEG2:
+              result.insert(entry.getElementaryPid()); break;
             default: break;
             }
             entry.advance();
diff --git a/lib/ts_stream.h b/lib/ts_stream.h
index 0620206c..4402ed35 100644
--- a/lib/ts_stream.h
+++ b/lib/ts_stream.h
@@ -9,7 +9,7 @@
 #include "shared_memory.h"
 
 namespace TS{
-  enum codecType{H264 = 0x1B, AAC = 0x0F, AC3 = 0x81, MP3 = 0x03, H265 = 0x24, ID3 = 0x15};
+  enum codecType{H264 = 0x1B, AAC = 0x0F, AC3 = 0x81, MP3 = 0x03, H265 = 0x24, ID3 = 0x15, MPEG2 = 0x02, MP2 = 0x03};
 
   class ADTSRemainder{
   private:
@@ -80,6 +80,9 @@ namespace TS{
     std::map<unsigned long, std::string> metaInit;
     std::map<unsigned long, std::string> descriptors;
     std::map<unsigned long, uint32_t> seenUnitStart;
+    std::map<unsigned long, std::string> mpeg2SeqHdr;
+    std::map<unsigned long, std::string> mpeg2SeqExt;
+    std::map<unsigned long, std::string> mp2Hdr;
     mutable tthread::recursive_mutex tMutex;
 
     bool threaded;
diff --git a/src/input/input_ts.cpp b/src/input/input_ts.cpp
index c6c0f756..2cce0346 100755
--- a/src/input/input_ts.cpp
+++ b/src/input/input_ts.cpp
@@ -123,8 +123,10 @@ namespace Mist {
     capa["priority"] = 9ll;
     capa["codecs"][0u][0u].append("H264");
     capa["codecs"][0u][0u].append("HEVC");
+    capa["codecs"][0u][0u].append("MPEG2");
     capa["codecs"][0u][1u].append("AAC");
     capa["codecs"][0u][1u].append("AC3");
+    capa["codecs"][0u][1u].append("MP2");
     inFile = NULL;
     inputProcess = 0;
   }
diff --git a/src/output/output_httpts.cpp b/src/output/output_httpts.cpp
index c5bbbe53..ddc26d2f 100644
--- a/src/output/output_httpts.cpp
+++ b/src/output/output_httpts.cpp
@@ -40,9 +40,11 @@ namespace Mist {
     capa["socket"] = "http_ts";
     capa["codecs"][0u][0u].append("H264");
     capa["codecs"][0u][0u].append("HEVC");
+    capa["codecs"][0u][0u].append("MPEG2");
     capa["codecs"][0u][1u].append("AAC");
     capa["codecs"][0u][1u].append("MP3");
     capa["codecs"][0u][1u].append("AC3");
+    capa["codecs"][0u][1u].append("MP2");
     capa["methods"][0u]["handler"] = "http";
     capa["methods"][0u]["type"] = "html5/video/mpeg";
     capa["methods"][0u]["priority"] = 1ll;
diff --git a/src/output/output_ts.cpp b/src/output/output_ts.cpp
index a97d31b7..9fc594d8 100644
--- a/src/output/output_ts.cpp
+++ b/src/output/output_ts.cpp
@@ -80,9 +80,11 @@ namespace Mist {
     capa["optional"]["tracks"]["default"] = "";
     capa["codecs"][0u][0u].append("HEVC");
     capa["codecs"][0u][0u].append("H264");
+    capa["codecs"][0u][0u].append("MPEG2");
     capa["codecs"][0u][1u].append("AAC");
     capa["codecs"][0u][1u].append("MP3");
     capa["codecs"][0u][1u].append("AC3");
+    capa["codecs"][0u][1u].append("MP2");
     cfg->addConnectorOptions(8888, capa);
     config = cfg;
     capa["push_urls"].append("tsudp://*");
diff --git a/src/output/output_ts_base.cpp b/src/output/output_ts_base.cpp
index 6c172c5f..3e16063e 100644
--- a/src/output/output_ts_base.cpp
+++ b/src/output/output_ts_base.cpp
@@ -81,115 +81,123 @@ namespace Mist {
     std::string bs;
     //prepare bufferstring    
     if (video){
-      unsigned int extraSize = 0;      
-      //dataPointer[4] & 0x1f is used to check if this should be done later: fillPacket("\000\000\000\001\011\360", 6);
-      if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
-        extraSize += 6;
-      }
-      if (keyframe){
-        if (Trk.codec == "H264"){
-          if (!haveAvcc){
-            avccbox.setPayload(Trk.init);
-            haveAvcc = true;
-          }
-          bs = avccbox.asAnnexB();
-          extraSize += bs.size();
+      if (Trk.codec == "H264" || Trk.codec == "HEVC"){
+        unsigned int extraSize = 0;      
+        //dataPointer[4] & 0x1f is used to check if this should be done later: fillPacket("\000\000\000\001\011\360", 6);
+        if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
+          extraSize += 6;
         }
-        /*LTS-START*/
-        if (Trk.codec == "HEVC"){
-          if (!haveHvcc){
-            hvccbox.setPayload(Trk.init);
-            haveHvcc = true;
+        if (keyframe){
+          if (Trk.codec == "H264"){
+            if (!haveAvcc){
+              avccbox.setPayload(Trk.init);
+              haveAvcc = true;
+            }
+            bs = avccbox.asAnnexB();
+            extraSize += bs.size();
           }
-          bs = hvccbox.asAnnexB();
-          extraSize += bs.size();
+          /*LTS-START*/
+          if (Trk.codec == "HEVC"){
+            if (!haveHvcc){
+              hvccbox.setPayload(Trk.init);
+              haveHvcc = true;
+            }
+            bs = hvccbox.asAnnexB();
+            extraSize += bs.size();
+          }
+          /*LTS-END*/
         }
-        /*LTS-END*/
-      }
-      
-      unsigned int watKunnenWeIn1Ding = 65490-13;
-      unsigned int splitCount = (dataLen+extraSize) / watKunnenWeIn1Ding;
-      unsigned int currPack = 0;
-      unsigned int ThisNaluSize = 0;
-      unsigned int i = 0;
-      unsigned int nalLead = 0;
-      uint64_t offset = thisPacket.getInt("offset") * 90;
+        
+        unsigned int watKunnenWeIn1Ding = 65490-13;
+        unsigned int splitCount = (dataLen+extraSize) / watKunnenWeIn1Ding;
+        unsigned int currPack = 0;
+        unsigned int ThisNaluSize = 0;
+        unsigned int i = 0;
+        unsigned int nalLead = 0;
+        uint64_t offset = thisPacket.getInt("offset") * 90;
 
-      while (currPack <= splitCount){
-        unsigned int alreadySent = 0;
-        bs = TS::Packet::getPESVideoLeadIn((currPack != splitCount ? watKunnenWeIn1Ding : dataLen+extraSize - currPack*watKunnenWeIn1Ding), packTime, offset, !currPack, Trk.bps);
-        fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
-        if (!currPack){
-          if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
-            //End of previous nal unit, if not already present
-            fillPacket("\000\000\000\001\011\360", 6, firstPack, video, keyframe, pkgPid, contPkg);
-            alreadySent += 6;
-          }
-          if (keyframe){
-            if (Trk.codec == "H264"){
-              bs = avccbox.asAnnexB();
-              fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
-              alreadySent += bs.size();
+        while (currPack <= splitCount){
+          unsigned int alreadySent = 0;
+          bs = TS::Packet::getPESVideoLeadIn((currPack != splitCount ? watKunnenWeIn1Ding : dataLen+extraSize - currPack*watKunnenWeIn1Ding), packTime, offset, !currPack, Trk.bps);
+          fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
+          if (!currPack){
+            if (Trk.codec == "H264" && (dataPointer[4] & 0x1f) != 0x09){
+              //End of previous nal unit, if not already present
+              fillPacket("\000\000\000\001\011\360", 6, firstPack, video, keyframe, pkgPid, contPkg);
+              alreadySent += 6;
             }
-            /*LTS-START*/
-            if (Trk.codec == "HEVC"){
-              bs = hvccbox.asAnnexB();
-              fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
-              alreadySent += bs.size();
+            if (keyframe){
+              if (Trk.codec == "H264"){
+                bs = avccbox.asAnnexB();
+                fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
+                alreadySent += bs.size();
+              }
+              /*LTS-START*/
+              if (Trk.codec == "HEVC"){
+                bs = hvccbox.asAnnexB();
+                fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
+                alreadySent += bs.size();
+              }
+              /*LTS-END*/
             }
-            /*LTS-END*/
           }
-        }
-        while (i + 4 < (unsigned int)dataLen){
-          if (nalLead){
-            fillPacket("\000\000\000\001"+4-nalLead,nalLead, firstPack, video, keyframe, pkgPid, contPkg);
-            i += nalLead;
-            alreadySent += nalLead;
-            nalLead = 0;
-          }
-          if (!ThisNaluSize){
-            ThisNaluSize = (dataPointer[i] << 24) + (dataPointer[i+1] << 16) + (dataPointer[i+2] << 8) + dataPointer[i+3];
-            if (ThisNaluSize + i + 4 > (unsigned int)dataLen){
-              DEBUG_MSG(DLVL_WARN, "Too big NALU detected (%u > %d) - skipping!", ThisNaluSize + i + 4, dataLen);
-              break;
+          while (i + 4 < (unsigned int)dataLen){
+            if (nalLead){
+              fillPacket("\000\000\000\001"+4-nalLead,nalLead, firstPack, video, keyframe, pkgPid, contPkg);
+              i += nalLead;
+              alreadySent += nalLead;
+              nalLead = 0;
             }
-            if (alreadySent + 4 > watKunnenWeIn1Ding){
-              nalLead = 4 - (watKunnenWeIn1Ding-alreadySent);
-              fillPacket("\000\000\000\001",watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg);
+            if (!ThisNaluSize){
+              ThisNaluSize = (dataPointer[i] << 24) + (dataPointer[i+1] << 16) + (dataPointer[i+2] << 8) + dataPointer[i+3];
+              if (ThisNaluSize + i + 4 > (unsigned int)dataLen){
+                DEBUG_MSG(DLVL_WARN, "Too big NALU detected (%u > %d) - skipping!", ThisNaluSize + i + 4, dataLen);
+                break;
+              }
+              if (alreadySent + 4 > watKunnenWeIn1Ding){
+                nalLead = 4 - (watKunnenWeIn1Ding-alreadySent);
+                fillPacket("\000\000\000\001",watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg);
+                i += watKunnenWeIn1Ding-alreadySent;
+                alreadySent += watKunnenWeIn1Ding-alreadySent;
+              }else{
+                fillPacket("\000\000\000\001",4, firstPack, video, keyframe, pkgPid, contPkg);
+                alreadySent += 4;
+                i += 4;
+              }
+            }
+            if (alreadySent + ThisNaluSize > watKunnenWeIn1Ding){
+              fillPacket(dataPointer+i,watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg);
               i += watKunnenWeIn1Ding-alreadySent;
+              ThisNaluSize -= watKunnenWeIn1Ding-alreadySent;
               alreadySent += watKunnenWeIn1Ding-alreadySent;
             }else{
-              fillPacket("\000\000\000\001",4, firstPack, video, keyframe, pkgPid, contPkg);
-              alreadySent += 4;
-              i += 4;
+              fillPacket(dataPointer+i,ThisNaluSize, firstPack, video, keyframe, pkgPid, contPkg);
+              alreadySent += ThisNaluSize;
+              i += ThisNaluSize;
+              ThisNaluSize = 0;
+            }          
+            if (alreadySent == watKunnenWeIn1Ding){
+              packData.addStuffing();
+              fillPacket(0, 0, firstPack, video, keyframe, pkgPid, contPkg);
+              firstPack = true;
+              break;
             }
           }
-          if (alreadySent + ThisNaluSize > watKunnenWeIn1Ding){
-            fillPacket(dataPointer+i,watKunnenWeIn1Ding-alreadySent, firstPack, video, keyframe, pkgPid, contPkg);
-            i += watKunnenWeIn1Ding-alreadySent;
-            ThisNaluSize -= watKunnenWeIn1Ding-alreadySent;
-            alreadySent += watKunnenWeIn1Ding-alreadySent;
-          }else{
-            fillPacket(dataPointer+i,ThisNaluSize, firstPack, video, keyframe, pkgPid, contPkg);
-            alreadySent += ThisNaluSize;
-            i += ThisNaluSize;
-            ThisNaluSize = 0;
-          }          
-          if (alreadySent == watKunnenWeIn1Ding){
-            packData.addStuffing();
-            fillPacket(0, 0, firstPack, video, keyframe, pkgPid, contPkg);
-            firstPack = true;
-            break;
-          }
+          currPack++;
         }
-        currPack++;
+      }else{
+        uint64_t offset = thisPacket.getInt("offset") * 90;
+        bs = TS::Packet::getPESVideoLeadIn(0, packTime, offset, true, Trk.bps);
+        fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
+
+        fillPacket(dataPointer, dataLen, firstPack, video, keyframe, pkgPid, contPkg);
       }
     }else if (Trk.type == "audio"){
       long unsigned int tempLen = dataLen;
       if (Trk.codec == "AAC"){
         tempLen += 7;
       }
-      bs = TS::Packet::getPESAudioLeadIn(tempLen, packTime, Trk.bps);// myMeta.tracks[thisPacket.getTrackId()].rate / 1000 );
+      bs = TS::Packet::getPESAudioLeadIn(tempLen, packTime, Trk.bps);
       fillPacket(bs.data(), bs.size(), firstPack, video, keyframe, pkgPid, contPkg);
       if (Trk.codec == "AAC"){        
         bs = TS::getAudioHeader(dataLen, Trk.init);