meeb / tubesync

Syncs YouTube channels and playlists to a locally hosted media server
GNU Affero General Public License v3.0
1.84k stars 119 forks source link

Saving as MP4 format #430

Open RtypeStudios opened 10 months ago

RtypeStudios commented 10 months ago

I've been trying to use tubesync (version 0.13.1) with Plex. The issues seems that Plex wont read metadata from MKV files. I was planning on writing a script that reads the file details out of the NFO (which plex also wont read). Then set the metadata on the mp4 file so that plex can ingest it.

Is there a way to set the output format? If not I'm happy to have a go at adding it.

MKV not read by plex:

meeb commented 10 months ago

The issue with using MP4 as a container is it doesn't, or didn't, support all the supported formats of the media streams from YouTube. Using MP4 restricts the codec choice and other options. MKV is the only container that supports all the available media streams as a container. It's possible to add, but you would need to also dynamically disable other format choices (and do a load of testing to find out what is and is not supported in the first place). It was easiest to hard code MKV containers.

It's possible to just select whatever input streams and then an MP4 output container with ffmpeg, but then you run the risk of doing actual transcoding (e.g. VP9 to x265 for the video stream or something) rather than just basic remuxing with no conversion which is what tubesync does at the moment and remuxing is of course massively preferable.

I use Plex myself and not reading some metadata from MKV files is indeed irritating.

RtypeStudios commented 10 months ago

Thank you for replying!

Oh interesting, I didn't know that. That does make it difficult and yeah of course you want to avoid the entire re-encoding.

I'm just trying to get the video titles into Plex. The videos show up grouped by year as the season, which is great. but each episode is named as a date. Have you managed to find a way to get the video title showing in plex?

I might try putting a script together that reads the NFO file and puts the episode information directly into Plex. Then if Plex dies you can just re-run the script again and re-import the information. Not perfect but it beats hand updating each video.

Thanks also for your great work on TubeSync and for embracing the self hosted ethos.

meeb commented 10 months ago

Honestly after many attempts ranging from basic up to advanced methods from specific file names up to scripts that spam data into Plex via the unofficial API I've ended up just having tubesync in its own Plex library and using the browse by folder option with media that has YYYY-MM-DD prefixes for sorting.

Hardly ideal, but it wasn't worth the fight in the end. There are existing metadata plugins for Plex that read NFO files that tubesync can optionally write, but Plex has made it a pain to manage the plugins now.

Jellyfin has better support from brief testing.

RtypeStudios commented 10 months ago

Ahh I thought there was an official API for Plex. Okay sounds like you have tried everything.

I tried Emby, which works. But I end up in the situation where Emby just jams everything in one season and sorts by the video title rather than the video date. I suspect I can fix that with a transform on the XML file. But i'd rather keep using Plex.

I will have a dig around and see if I can spot anything. but sounds like a lost cause.

meeb commented 10 months ago

I must admit I've not really looked into it for a while after I got annoyed with it last time. If you find something that works well feel free to share!

RtypeStudios commented 10 months ago

This seems to work okay. Updates a few hundred videos pretty quickly, It is just a proof of concept but it seems to work. I'm off to bed, but will improve on it tomorrow.

pip install plexapi pip install lxml

import os
from pathlib import Path
from plexapi.server import PlexServer
import lxml.etree as ET

baseurl = 'http://plex.lan:32400'
token = '<your token>'

plex = PlexServer(baseurl, token)

videos = plex.library.section('TubeSync')

for video in videos.search(unwatched=True):
    for part in video.iterParts():
        nfo_data_file_path = part.file.replace(".mkv", ".nfo")
        nfo_data_file_path = '/mnt' + nfo_data_file_path

        print(nfo_data_file_path)

        if os.path.exists(nfo_data_file_path):
            parser = ET.XMLParser(recover=True)
            tree = ET.parse(nfo_data_file_path, parser=parser)
            root = tree.getroot()
            video.editTitle(root.find('title').text, locked=True)
            video.editSortTitle(root.find('aired').text, locked=True)