2024-06-05, 01:57
Hey,
I would love to be able to convert from one format to another directly from a Python addon. For instance I have a folder with wav recordings which I would like to convert to MP3 using my Python addon. Pure Python would be slow and tedious, so I thought why not using FFmpeg. Shipping a standalone library/binary would be too much effort, and it wouldn't necessarily work on all platforms Kodi can run on. However I realized that the kodi binary already has ffmpeg (or rather libav) functions globally exported:
I have grepped for all the functions I would need and figured that its technically doable. So then I tried using ctypes. First I wrote some simple code to check if I can get version info at least:
But then I got:
That makes sense I guess since kodi was compiled without the no pie flag. Overall that's a great protection. But I am wondering, is there no other tricky way I could utilize so I could call these methods from Python somehow? Even if it requires a second Kodi process to run and using ptrace or some stuff to manipulate what's being run.
My goal would be to target Linux and Android hosts at least. Windows would be secondary and the rest I don't care about much.
Thanks for the ideas!
I would love to be able to convert from one format to another directly from a Python addon. For instance I have a folder with wav recordings which I would like to convert to MP3 using my Python addon. Pure Python would be slow and tedious, so I thought why not using FFmpeg. Shipping a standalone library/binary would be too much effort, and it wouldn't necessarily work on all platforms Kodi can run on. However I realized that the kodi binary already has ffmpeg (or rather libav) functions globally exported:
Code:
readelf -a --wide /usr/lib/kodi/kodi.bin | grep 'avformat_open_input'
17377: 00000000021fbff0 1759 FUNC GLOBAL DEFAULT 12 avformat_open_input
I have grepped for all the functions I would need and figured that its technically doable. So then I tried using ctypes. First I wrote some simple code to check if I can get version info at least:
Code:
import ctypes
import sys
kodi_bin = ctypes.CDLL('/usr/lib/kodi/kodi.bin')
kodi_bin.av_version_info.restype = ctypes.c_char_p
def print_ffmpeg_version():
version_info = kodi_bin.av_version_info()
if version_info:
version_string = version_info.decode('utf-8')
print(version_string, file=sys.stderr)
else:
print("Could not retrieve FFmpeg version information", file=sys.stderr)
print_ffmpeg_version()
But then I got:
Code:
Error Type: <class 'OSError'>
Error Contents: /usr/lib/kodi/kodi.bin: cannot dynamically load position-independent executable
Traceback (most recent call last):
File "/home/mrdini/.kodi/addons/plugin.video.testaddon/default.py", line 9, in <module>
kodi_bin = ctypes.CDLL('/usr/lib/kodi/kodi.bin', use_errno=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/ctypes/__init__.py", line 379, in __init__
self._handle = _dlopen(self._name, mode)
^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: /usr/lib/kodi/kodi.bin: cannot dynamically load position-independent executable
That makes sense I guess since kodi was compiled without the no pie flag. Overall that's a great protection. But I am wondering, is there no other tricky way I could utilize so I could call these methods from Python somehow? Even if it requires a second Kodi process to run and using ptrace or some stuff to manipulate what's being run.
My goal would be to target Linux and Android hosts at least. Windows would be secondary and the rest I don't care about much.
Thanks for the ideas!