Twitch-Stream-Recorder

Auf Github gibt es jetzt den Twitch-Stream-Recorder, dieser setzt auf die twitch-cli über die automatisch immer ein gültiger Token zur Verfügung gestellt wird.

https://github.com/DravenTec/Twitch-Stream-Recorder

Veröffentlicht unter Allgemein | Schreib einen Kommentar

Twitch Recoder with New Api

Da Twitch seine API aktualisiert bzw. jetzt die alte API abgeschaltet hat musste im selben Zug auch mein Twitch Recorder Script angepasst werden.

Das Original Script stammt von  junian https://gist.github.com/junian/b41dd8e544bf0e3980c971b0d015f5f6

Nach meinen Anpassung funktioniert das Script wieder, aber es gibt auch schon einen Fork vom Original was ebenfalls auf die neue API setzt.

# This code is based on tutorial by slicktechies modified as needed to use oauth token from Twitch.
# You can read more details at: https://www.junian.net/2017/01/how-to-record-twitch-streams.html
# original code is from https://slicktechies.com/how-to-watchrecord-twitch-streams-using-livestreamer/

import requests
import os
import time
import json
import sys
import subprocess
import datetime
import getopt

class TwitchRecorder:
    def __init__(self):
        # global configuration
        self.client_id = "" # insert your own Client-ID
        # get oauth token value by typing `streamlink --twitch-oauth-authenticate` in terminal
        self.oauth_token = ""
        self.ffmpeg_path = 'ffmpeg'
        self.refresh = 15.0
        self.root_path = "" # folder for saving files
        
        # user configuration
        self.username = "" # insert streamer 
        self.quality = "best"

    def run(self):
        # path to recorded stream
        self.recorded_path = os.path.join(self.root_path, "recorded", self.username)

        # path to finished video, errors removed
        self.processed_path = os.path.join(self.root_path, "processed", self.username)

        # create directory for recordedPath and processedPath if not exist
        if(os.path.isdir(self.recorded_path) is False):
            os.makedirs(self.recorded_path)
        if(os.path.isdir(self.processed_path) is False):
            os.makedirs(self.processed_path)

        # make sure the interval to check user availability is not less than 15 seconds
        if(self.refresh < 15):
            print("Check interval should not be lower than 15 seconds.")
            self.refresh = 15
            print("System set check interval to 15 seconds.")
        
        # fix videos from previous recording session
        try:
            video_list = [f for f in os.listdir(self.recorded_path) if os.path.isfile(os.path.join(self.recorded_path, f))]
            if(len(video_list) > 0):
                print('Fixing previously recorded files.')
            for f in video_list:
                recorded_filename = os.path.join(self.recorded_path, f)
                print('Fixing ' + recorded_filename + '.')
                try:
                    subprocess.call([self.ffmpeg_path, '-err_detect', 'ignore_err', '-i', recorded_filename, '-c', 'copy', os.path.join(self.processed_path,f)])
                    os.remove(recorded_filename)
                except Exception as e:
                    print(e)
        except Exception as e:
            print(e)

        print("Checking for", self.username, "every", self.refresh, "seconds. Record with", self.quality, "quality.")
        self.loopcheck()

    def check_user(self):
        # 0: online, 
        # 1: offline, 
        # 2: not found, 
        # 3: error
        headers = {
              'Authorization' : 'Bearer ' + self.oauth_token,
              'Client-ID' : self.client_id
              }
        
        url = 'https://api.twitch.tv/helix/streams?user_login=' + self.username
        info = None
        status = 3
        try:
            r = requests.get(url, headers = headers, timeout = 15)
            r.raise_for_status()
            info = r.json()
            if 'type' in str(info):
             status = 0
            else:
             status = 1 
        except requests.exceptions.RequestException as e:
            if e.response:
                if e.response.reason == 'Not Found' or e.response.reason == 'Unprocessable Entity':
                    status = 2

        return status, info

    def loopcheck(self):
        while True:
            status, info = self.check_user()
            if status == 2:
                print("Username not found. Invalid username or typo.")
                time.sleep(self.refresh)
            elif status == 3:
                print(datetime.datetime.now().strftime("%Hh%Mm%Ss")," ","unexpected error. will try again in 5 minutes.")
                time.sleep(300)
            elif status == 1:
                print(self.username, "currently offline, checking again in", self.refresh, "seconds.")
                time.sleep(self.refresh)
            elif status == 0:
                print(self.username, "online. Stream recording in session.")
                filename = self.username + " - " + datetime.datetime.now().strftime("%Y-%m-%d %Hh%Mm%Ss") + " - " + info['data'][0]['title'] + ".mp4"
                
                # clean filename from unecessary characters
                filename = "".join(x for x in filename if x.isalnum() or x in [" ", "-", "_", "."])
                
                recorded_filename = os.path.join(self.recorded_path, filename)
                
                # start streamlink process
                subprocess.call(["streamlink", "--twitch-oauth-token", self.oauth_token, "twitch.tv/" + self.username, self.quality, "-o", recorded_filename])

                print("Recording stream is done. Fixing video file.")
                if(os.path.exists(recorded_filename) is True):
                    try:
                        subprocess.call([self.ffmpeg_path, '-err_detect', 'ignore_err', '-i', recorded_filename, '-c', 'copy', os.path.join(self.processed_path, filename)])
                        os.remove(recorded_filename)
                    except Exception as e:
                        print(e)
                else:
                    print("Skip fixing. File not found.")
                    
                print("Fixing is done. Going back to checking..")
                time.sleep(self.refresh)

def main(argv):
    twitch_recorder = TwitchRecorder()
    usage_message = 'twitch-recorder.py -u <username> -q <quality>'

    try:
        opts, args = getopt.getopt(argv,"hu:q:",["username=","quality="])
    except getopt.GetoptError:
        print (usage_message)
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print(usage_message)
            sys.exit()
        elif opt in ("-u", "--username"):
            twitch_recorder.username = arg
        elif opt in ("-q", "--quality"):
            twitch_recorder.quality = arg

    twitch_recorder.run()

if __name__ == "__main__":
    main(sys.argv[1:])
Veröffentlicht unter IT | Verschlagwortet mit , , , , , | Schreib einen Kommentar

Xenserver/XCP-ng komplette Festplatte an eine VM weiterreichen

Den Original Artikel findet Ihr unter diesem Link https://www.zerodispersion.com/xenserver-whole-disk-passthrough/

Hier eine kurze Übersetzung und eine Erinnerung für mich wenn ich es irgendwann nochmal machen muss…

In der Console von XenServer bzw. XCP-ng muss folgendes eingegeben werden. 

  1. mkdir /srv/YOUR_SR_NAME
  2. xe sr-create name-label=”MY BLOCK SR” name-description=”MY BLOCK SR” type=udev content-type=disk device-config:location=/srv/YOUR_SR_NAME
  3. ln -s /dev/sdb /srv/YOUR_SR_NAME/sdb
  4. xe sr-scan uuid=YOUR_NEW_UUID
  5. xe vdi-list sr-uuid=YOUR_NEW_UUID
 
Erklärung 
  1. Es wird ein neuer Ordner unter /srv für das Storage repository erstellt. Man kann auch einen anderen Ordner nehmen wenn man möchte es müssen dann nur die Einträge gegebenenfalls angepasst werden
  2. Hiermit wird ein neues Storage Repository (SR) erstellt. Der Name für das SR kann frei gewählt werden dazu einfach „MY BLOCK SR“ mit dem gewünschten Namen des SR ersetzen. Dieses neue SR wird dann mit dem zuvor erstellten Ordner verknüpft.
  3. In unserem Beispiel soll die Festplatte „sdb“ an die VM weitergereicht werden. Deshalb erstellen wir hier einen Softlink zu dem zuvor erstellten Ordner
  4. Durch den Befehl sucht XenServer/XCP-ng nach dem neuen SR
  5. Nach diesem letzten Befehl sollte das neue SR in XenServer/XCP-ng angezeigt werden

Über das XenCenter oder XCP-ng Center lässt sich nun das neue SR einer VM zuordnen.

 
Veröffentlicht unter Allgemein | Schreib einen Kommentar

Vodafone DSL mit altem „Analog“ Anschluss

Für alle Leute die noch einen alten Vodafone Anschluss haben mit „Analog“ Telefon!

In den alten Verträgen gab es noch einen Analog Anschluss dieser ist allerdings KEIN Analog Anschluss. Vodafone hat anstatt eines Analog Anschluss eine ISDN Anschluss mit nur einer Rufnummer sowie eingeschränkten Funktionen eingesetzt. Dieses musste ich bei einem Wechsel von der Easybox 802 zur Fritz!Box 7490 feststellen. Wer also einen Wechsel plant ohne seinen Vertrag zu ändern sollte berücksichtigen das er dann zur Fritz!Box noch einen Splitter sowie NTBA benötigt. Diese Information findet man leider auch in den Foren von Vodafone nicht.

Da ich an meinem Wohnort allerdings nur DSL16 bekomme möchte ich die schon magere Bandbreite nicht mit einem VoIP Anschluss noch weiter minimieren. Deshalb bin ich auf meinem vorhandenen Anschluss mit Analog-ISDN angewiesen. Willkommen im Fortschrittlichen Deutschland wo man selbst in Städten meist nicht über DSL6 oder DSL16 hinaus kommt.

Veröffentlicht unter IT | Schreib einen Kommentar

Microsoft Flight Simulator X + Acceleration Expansion (Gold Edition)

Nach langer Zeit wollte ich mal wieder eine Runde im FSX drehen. Eigentlich dachte ich das ich es zuletzt unter dem aktuellen Betriebssystem installiert hatte… tja wer denkt ist selber schuld.
Als ich versuchte es zu starten kam auch sogleich eine Fehlermeldung das es nicht richtig installiert ist. Leider ließ sich die Installation auch nicht mit den CDs wieder zum Leben erwecken.
Also mal eben neuinstallieren, Key eingeben und aktivieren. Key ungültig…

Zum Glück lag noch von der letzten Installation ein Zettel in der Schachtel.
Bei Key ungültig. Service Pack installieren
Beim nächsten Mal werde ich mir genauer aufschreiben was zu machen ist. Den es ist einem leider nicht geholfen nur das Service Pack 1 zu installieren auch dann ist der Key weiterhin ungültig. Allerdings ließ sich auch das Acceleration Pack sich nicht installieren in dem das Service Pack 2 eigentlich vorhanden ist den vorher möchte eben dieses dass der FSX aktiviert wird, was aber nur mit einem gültigen Key geht. Da ich im Internet diesmal kein Google Erfolg hatte gibt es hier einmal eine Anleitung zum Installieren.
Weiterlesen

Veröffentlicht unter Games | Schreib einen Kommentar

Windows konnte nicht alle Netzwerk-Laufwerke verbinden

Beim Einsatz einer SSD kann es vorkommen das Windows zu schnell startet.
Was dazu führen kann das nicht alle Dienste geladen sind wenn sie benötigt werden.
Dies tritt auch gerne beim Netzwerk auf besonders in Verwendung mit DHCP aber auch mit festen IP Einstellungen.

Werden dann Netzwerk-Laufwerke automatisch verbunden kann es passieren das Windows
sagt das die Netzwerk-Laufwerke nicht verbunden werden konnten. Um dieses zu verhindern
kann man in den Pro Versionen in den Gruppenrichtlinien einstellen das Windows auf das Netzwerk warten soll.

Für Windows 7 (ab Pro):
1) „Windows+R“ dann „gpedit.msc“ eingeben
2) „Computerkonfiguration“ – „Administrative Vorlagen
3) „System“ -„Anmelden
4) „Bei Neustart des Computers und bei der Anmeldung auf das Netzwerk warten“ aktivieren

Für Windows XP/Vista/7:
1) „Windows+R“ dann „regedit“ eingeben
2) Zu „HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\CurrentVersion\Winlogon“ wechseln
3) Einen „DWORD-Wert (32-Bit)“ erstellen Namens „SyncForegroundPolicy
4) Den Wert auf „1“ stellen
SyncForegroundPolicy

Veröffentlicht unter IT | Schreib einen Kommentar

Etwas Neues im Hause: Lenovo ThinkPad Edge E531 – 6885-26G

Neben meinem ThinkPad x61 Tablet hat jetzt noch ein stärkeres größeres Modell den Weg zu mir gefunden.

Es ist allerdings kein Neugerät sondern ein Demogerät geworden. Im Zustand AAA an dem Laptop war absolut nichts.

Getauft wurde er auf den Namen Lupus, das x61 hat den Namen Corvus.

Technische Details:

  • Intel Core i7-3632QM (4x 2,2GHz / 6MB Cache / 64 Bit / 35 Watt)
  • 15,6 Zoll TFT (1920×1080)
  • 8GB DDR3 (2x 4GB)
  • 1x 24GB Mini PCI-E SSD / 1x 1TB WD Blue 5400RPM
  • 8x DVD+/-RW DDL Brenner
  • Nvidia Optimus (Intel HD4000 + Nvidia GeForce GT740M (2GB))
  • Low Light HD Webcam (Anm.: Ich habe schon lange keine mehr gebraucht)
  • ThinkPad Wireless LAN 802.11b/g/n
  • 5-1 CardReader (SD/MMC/MS/XD)
  • Windows 8 Pro (beworben mit Windows 7 aber dazu später mehr)

Bevor überhaupt großartig was gemacht wurde habe ich die WD Festplatte gegen eine Samsung SSD (250 GB Samsung EVO) getauscht.

Da ein Notebook von mir gerne mal bewegt wird im Betrieb setze ich lieber auf eine SSD. Die 1TB Festplatte kommt in ein ext. Gehäuse.

Veröffentlicht unter IT | Schreib einen Kommentar

Sturm in Bochum

Leider keine Bilder wo es losging dafür aber ein paar nächtliche was er für einen Schaden angerichtet hat.
Weiterlesen

Veröffentlicht unter Allgemein | Schreib einen Kommentar

Linux und 4TB Festplatten

Um eine 4TB Festplatte unter Linux zu benutzen empfiehlt es sich
mit parted die Einrichtung vorzunehmen.
Unter Ubuntu/Debian kann man parted mit folgendem Befehl installieren
sudo apt-get update & sudo apt-get install parted
Anschließend startet man parted mit dem Befehl
sudo parted /dev/sdd
In diesem Bsp. wird die vierte Festplatte aufgerufen.
GNU Parted 2.1
Using /dev/sdd
Welcome to GNU Parted! Type 'help' to view a list of commands.

Weiterlesen

Veröffentlicht unter IT, Linux | Schreib einen Kommentar

Raspberry PI und die License keys

Wer die License keys eintragen will muss sich via ssh auf seinen Raspberry verbinden. Anschließend mit mount /flash -o remount,rw
den Ordner /flash beschreibbar machen.
Mit nano /flash/config.txt kann die Datei bearbeitet werden.
Nun einfach die # vor decode_MPG2 bzw. decode_WVC1 entfernen und dahinter den License Code eingeben. Mit Strg+O speichert man das ganze danach das System mit reboot einmal neustarten.

Wenn man testen möchte ob alles geklappt hat anschließend nochmals mit ssh verbinden und folgendes eingeben: vcgencmd codec_enabled MPG2 bzw. vcgencmd_enabled WCV1 es sollte dann angezeigt werden MPG2=enabled bzw. WCV1=enabled

Veröffentlicht unter IT, Linux | Schreib einen Kommentar