
Recherche avancée
Médias (91)
-
Spitfire Parade - Crisis
15 mai 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
Wired NextMusic
14 mai 2011, par
Mis à jour : Février 2012
Langue : English
Type : Video
-
Video d’abeille en portrait
14 mai 2011, par
Mis à jour : Février 2012
Langue : français
Type : Video
-
Sintel MP4 Surround 5.1 Full
13 mai 2011, par
Mis à jour : Février 2012
Langue : English
Type : Video
-
Carte de Schillerkiez
13 mai 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Texte
-
Publier une image simplement
13 avril 2011, par ,
Mis à jour : Février 2012
Langue : français
Type : Video
Autres articles (100)
-
Soumettre améliorations et plugins supplémentaires
10 avril 2011Si vous avez développé une nouvelle extension permettant d’ajouter une ou plusieurs fonctionnalités utiles à MediaSPIP, faites le nous savoir et son intégration dans la distribution officielle sera envisagée.
Vous pouvez utiliser la liste de discussion de développement afin de le faire savoir ou demander de l’aide quant à la réalisation de ce plugin. MediaSPIP étant basé sur SPIP, il est également possible d’utiliser le liste de discussion SPIP-zone de SPIP pour (...) -
MediaSPIP Init et Diogène : types de publications de MediaSPIP
11 novembre 2010, parÀ l’installation d’un site MediaSPIP, le plugin MediaSPIP Init réalise certaines opérations dont la principale consiste à créer quatre rubriques principales dans le site et de créer cinq templates de formulaire pour Diogène.
Ces quatre rubriques principales (aussi appelées secteurs) sont : Medias ; Sites ; Editos ; Actualités ;
Pour chacune de ces rubriques est créé un template de formulaire spécifique éponyme. Pour la rubrique "Medias" un second template "catégorie" est créé permettant d’ajouter (...) -
XMP PHP
13 mai 2011, parDixit Wikipedia, XMP signifie :
Extensible Metadata Platform ou XMP est un format de métadonnées basé sur XML utilisé dans les applications PDF, de photographie et de graphisme. Il a été lancé par Adobe Systems en avril 2001 en étant intégré à la version 5.0 d’Adobe Acrobat.
Étant basé sur XML, il gère un ensemble de tags dynamiques pour l’utilisation dans le cadre du Web sémantique.
XMP permet d’enregistrer sous forme d’un document XML des informations relatives à un fichier : titre, auteur, historique (...)
Sur d’autres sites (8100)
-
Flask app using OpenCv crash when i start recording
17 mai 2023, par Mulham DarwishI build this flask app to live stream security cameras and the live stream works with the screenshot function but when start recording it crash but few times same code it worked and saved the video here the code. with the html file using js.


from flask import Flask, render_template, Response, request
import cv2
import os
import time
import threading
import requests

app = Flask(__name__)

# Define the IP cameras
cameras = [
 {'url': 'rtsp://****:*****@******', 'name': 'Camera 1'},
 {'url': 'rtsp://****:*****@******', 'name': 'Camera 2'},
 {'url': 'rtsp://****:*****@******', 'name': 'Camera 3'},
 {'url': 'rtsp://****:*****@******', 'name': 'Camera 4'}
]

# Create a VideoCapture object for each camera
capture_objs = [cv2.VideoCapture(cam['url']) for cam in cameras]
stop_events = {i: threading.Event() for i in range(len(cameras))}
# Define the directory to save the recorded videos
recording_dir = os.path.join(os.getcwd(), 'recordings')

# Ensure the recording directory exists
if not os.path.exists(recording_dir):
 os.makedirs(recording_dir)

# Define the function to capture and save a video
def record_video(camera_index, stop_recording):
 # Define the codec and file extension
 fourcc = cv2.VideoWriter_fourcc(*'mp4v')
 file_extension = '.mp4'

 # Get the current timestamp for the filename
 timestamp = time.strftime("%Y%m%d-%H%M%S")

 # Define the filename and path
 filename = f'{cameras[camera_index]["name"]}_{timestamp}{file_extension}'
 filepath = os.path.join(recording_dir, filename)

 # Create a VideoWriter object to save the video
 width = int(capture_objs[camera_index].get(cv2.CAP_PROP_FRAME_WIDTH))
 height = int(capture_objs[camera_index].get(cv2.CAP_PROP_FRAME_HEIGHT))
 fps = int(capture_objs[camera_index].get(cv2.CAP_PROP_FPS))
 video_writer = cv2.VideoWriter(filepath, fourcc, fps, (width, height))

 # Capture frames and write them to the file
 while True:
 if stop_recording.is_set():
 break # stop recording if stop_recording is set
 ret, frame = capture_objs[camera_index].read()
 if ret:
 video_writer.write(frame)
 else:
 break

 # Release the VideoWriter object and the VideoCapture object
 video_writer.release()
 capture_objs[camera_index].release()

@app.route('/')
def index():
 # Render the index page with the list of cameras
 return render_template('index.html', cameras=cameras)

def generate(camera_index):
 # Generate frames from the video feed
 while True:
 ret, frame = capture_objs[camera_index].read()
 if not ret:
 break

 # Encode the frame as JPEG
 _, jpeg = cv2.imencode('.jpg', frame)

 # Yield the frame as a Flask response
 yield (b'--frame\r\n'
 b'Content-Type: image/jpeg\r\n\r\n' + jpeg.tobytes() + b'\r\n')

@app.route('/video_feed')
def video_feed():
 # Get the camera index from the request arguments
 camera_index = int(request.args.get('camera_index'))

 # Generate the video feed
 return Response(generate(camera_index),
 mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/record', methods=['POST'])
def record():
 # Get the camera index from the request form
 camera_index = int(request.form['camera_index'])

 stop_recording = stop_events[camera_index] # get the stop_recording event for the camera
 thread = threading.Thread(target=record_video, args=(camera_index, stop_recording))
 thread.start() # start a thread to record video

 # Return a response indicating that the recording has started
 return 'Recording started.'

@app.route('/stop_record', methods=['POST'])
def stop_record():
 # Get the camera index from the request form
 camera_index = int(request.form['camera_index'])

 # Set the stop_recording event for the corresponding camera thread
 stop_events[camera_index].set()

 # Return a response indicating that recording has been stopped
 return 'Recording stopped.'

@app.route('/screenshot', methods=['POST'])
def take_screenshot():
 # Take a screenshot of the video stream and save it as a file
 camera = capture_objs[int(request.form['camera_id'])]
 success, frame = camera.read()
 if success:
 timestamp = time.strftime("%Y%m%d-%H%M%S")
 filename = f'screenshot_{timestamp}.jpg'
 cv2.imwrite(filename, frame)
 return 'Screenshot taken and saved'
 else:
 return 'Failed to take screenshot'

if __name__ == '__main__':
 app.run()



I tried to update ffmpeg to the latest version and installed pip install opencv-python-headless and installed pip install opencv-python but most of the time i come to this crash code


* Serving Flask app 'run'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
127.0.0.1 - - [17/May/2023 13:24:11] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=0 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=1 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=2 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:11] "GET /video_feed?camera_index=3 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:44] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=3 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=0 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=1 HTTP/1.1" 200 -
127.0.0.1 - - [17/May/2023 13:24:45] "GET /video_feed?camera_index=2 HTTP/1.1" 200 -
[h264 @ 0x5605285fc5c0] error while decoding MB 28 29, bytestream -9
[h264 @ 0x560529110040] error while decoding MB 15 37, bytestream -6
[h264 @ 0x560528624980] error while decoding MB 45 45, bytestream -23
[h264 @ 0x5605286f1900] error while decoding MB 50 34, bytestream -7
[h264 @ 0x5605285fc5c0] error while decoding MB 25 9, bytestream -17
[h264 @ 0x5605292b0080] error while decoding MB 28 41, bytestream -5
[h264 @ 0x560528660040] error while decoding MB 101 45, bytestream -17
[h264 @ 0x5605285fc5c0] error while decoding MB 42 44, bytestream -5
[h264 @ 0x5605286f1900] error while decoding MB 118 42, bytestream -9
[h264 @ 0x560529110040] error while decoding MB 92 43, bytestream -5
[h264 @ 0x560528660040] error while decoding MB 99 34, bytestream -11
[h264 @ 0x56052932b0c0] error while decoding MB 92 36, bytestream -13
[h264 @ 0x560528667ac0] error while decoding MB 44 54, bytestream -5
[h264 @ 0x560529110040] error while decoding MB 93 33, bytestream -7
[h264 @ 0x5605286dd880] error while decoding MB 27 37, bytestream -19
[h264 @ 0x560528660040] error while decoding MB 66 56, bytestream -9
127.0.0.1 - - [17/May/2023 13:36:45] "POST /record HTTP/1.1" 200 -
Assertion fctx->async_lock failed at libavcodec/pthread_frame.c:175
Aborted (core dumped)



-
I am trying to use the RTSPPlay, project of mooncatventures. But it shows me error like this
7 octobre 2013, par kamlesh shingarakhiyaI am trying to use the RTSPPlay, project of mooncatventures. But it shows me error like this.
Ld /Users/admin/Library/Developer/Xcode/DerivedData/Intercom-bpixnryueeelexfnzxtmgchcfgzq/Build/Products/Debug-iphonesimulator/Intercom.app/Intercom normal i386
cd /Volumes/IPHONE/Intercom
setenv IPHONEOS_DEPLOYMENT_TARGET 6.1
setenv PATH "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk -L/Users/admin/Library/Developer/Xcode/DerivedData/Intercom-bpixnryueeelexfnzxtmgchcfgzq/Build/Products/Debug-iphonesimulator -F/Users/admin/Library/Developer/Xcode/DerivedData/Intercom-bpixnryueeelexfnzxtmgchcfgzq/Build/Products/Debug-iphonesimulator -F/Users/admin/Downloads/RTSPPlay-master -filelist /Users/admin/Library/Developer/Xcode/DerivedData/Intercom-bpixnryueeelexfnzxtmgchcfgzq/Build/Intermediates/Intercom.build/Debug-iphonesimulator/Intercom.build/Objects-normal/i386/Intercom.LinkFileList -Xlinker -objc_abi_version -Xlinker 2 -Xlinker -no_implicit_dylibs -fobjc-link-runtime -mios-simulator-version-min=6.1 -framework FFmpegDecoder -framework FFPlayer -framework SDL -framework OpenGLES -framework MediaPlayer -framework CoreMedia -framework CoreVideo -framework MobileCoreServices -framework AVFoundation -framework CFNetwork -lbz2 -lxml2 -lz.1.1.3 -lz -framework QuartzCore -framework Security -framework SystemConfiguration -framework UIKit -framework Foundation -framework CoreGraphics -o /Users/admin/Library/Developer/Xcode/DerivedData/Intercom-bpixnryueeelexfnzxtmgchcfgzq/Build/Products/Debug-iphonesimulator/Intercom.app/Intercom
Undefined symbols for architecture i386:
"_SDL_AddTimer", referenced from:
_SDL_main in FFPlayer(main.o)
"_SDL_CloseAudio", referenced from:
_stream_component_close in FFPlayer(main.o)
"_SDL_CondSignal", referenced from:
_SDL_main in FFPlayer(main.o)
_stream_component_close in FFPlayer(main.o)
_packet_queue_abort in FFPlayer(main.o)
_packet_queue_put in FFPlayer(main.o)
"_SDL_CondWait", referenced from:
_video_thread in FFPlayer(main.o)
_subtitle_thread in FFPlayer(main.o)
_packet_queue_get in FFPlayer(main.o)
"_SDL_CreateCond", referenced from:
_SDL_main in FFPlayer(main.o)
_packet_queue_init in FFPlayer(main.o)
"_SDL_CreateMutex", referenced from:
_SDL_main in FFPlayer(main.o)
_packet_queue_init in FFPlayer(main.o)
"_SDL_CreateRGBSurface", referenced from:
_SDL_main in FFPlayer(main.o)
_video_open in FFPlayer(main.o)
"_SDL_CreateRenderer", referenced from:
_SDL_main in FFPlayer(main.o)
"_SDL_CreateThread", referenced from:
_SDL_main in FFPlayer(main.o)
_stream_component_open in FFPlayer(main.o)
"_SDL_CreateWindow", referenced from:
_SDL_main in FFPlayer(main.o)
"_SDL_Delay", referenced from:
_video_thread in FFPlayer(main.o)
_subtitle_thread in FFPlayer(main.o)
_decode_thread in FFPlayer(main.o)
"_SDL_DestroyCond", referenced from:
_do_exit in FFPlayer(main.o)
_stream_component_close in FFPlayer(main.o)
"_SDL_DestroyMutex", referenced from:
_do_exit in FFPlayer(main.o)
_stream_component_close in FFPlayer(main.o)
"_SDL_DestroyTexture", referenced from:
_video_display in FFPlayer(main.o)
"_SDL_EventState", referenced from:
_SDL_main in FFPlayer(main.o)
"_SDL_FillRect", referenced from:
_video_display in FFPlayer(main.o)
"_SDL_FreeSurface", referenced from:
_SDL_main in FFPlayer(main.o)
_do_exit in FFPlayer(main.o)
"_SDL_GL_SetAttribute", referenced from:
_SDL_main in FFPlayer(main.o)
"_SDL_Init", referenced from:
_SDL_main in FFPlayer(main.o)
"_SDL_LockSurface", referenced from:
_video_thread in FFPlayer(main.o)
"_SDL_MapRGB", referenced from:
_video_display in FFPlayer(main.o)
"_SDL_OpenAudio", referenced from:
_stream_component_open in FFPlayer(main.o)
"_SDL_PauseAudio", referenced from:
_stream_component_open in FFPlayer(main.o)
"_SDL_PixelFormatEnumToMasks", referenced from:
_SDL_main in FFPlayer(main.o)
_video_open in FFPlayer(main.o)
"_SDL_PollEvent", referenced from:
_SDL_main in FFPlayer(main.o)
"_SDL_PushEvent", referenced from:
_sdl_refresh_timer_cb in FFPlayer(main.o)
_video_thread in FFPlayer(main.o)
_decode_thread in FFPlayer(main.o)
"_SDL_RenderPresent", referenced from:
_video_display in FFPlayer(main.o)
"_SDL_SendQuit", referenced from:
-[SDLUIKitDelegate quitSdl] in SDL_uikitappdelegate.o
-[SDLUIKitDelegate applicationWillTerminate:] in SDL_uikitappdelegate.o
-[SDLUIKitDelegate applicationDidEnterBackground:] in SDL_uikitappdelegate.o
"_SDL_UnlockSurface", referenced from:
_video_thread in FFPlayer(main.o)
"_SDL_WaitEvent", referenced from:
_SDL_main in FFPlayer(main.o)
"_SDL_WaitThread", referenced from:
_do_exit in FFPlayer(main.o)
_stream_component_close in FFPlayer(main.o)
"_SDL_mutexP", referenced from:
_SDL_main in FFPlayer(main.o)
_stream_component_close in FFPlayer(main.o)
_video_thread in FFPlayer(main.o)
_subtitle_thread in FFPlayer(main.o)
_packet_queue_get in FFPlayer(main.o)
_packet_queue_abort in FFPlayer(main.o)
_packet_queue_flush in FFPlayer(main.o)
...
"_SDL_mutexV", referenced from:
_SDL_main in FFPlayer(main.o)
_stream_component_close in FFPlayer(main.o)
_video_thread in FFPlayer(main.o)
_subtitle_thread in FFPlayer(main.o)
_packet_queue_get in FFPlayer(main.o)
_packet_queue_abort in FFPlayer(main.o)
_packet_queue_flush in FFPlayer(main.o)
...
"_av_audio_convert", referenced from:
_sdl_audio_callback in FFPlayer(main.o)
"_av_audio_convert_alloc", referenced from:
_sdl_audio_callback in FFPlayer(main.o)
"_av_audio_convert_free", referenced from:
_stream_component_close in FFPlayer(main.o)
_sdl_audio_callback in FFPlayer(main.o)
"_av_bitstream_filter_next", referenced from:
_show_formats in cmdutils.o
"_av_close_input_file", referenced from:
_decode_thread in FFPlayer(main.o)
"_av_codec_next", referenced from:
_show_formats in cmdutils.o
"_av_dup_packet", referenced from:
_packet_queue_put in FFPlayer(main.o)
"_av_find_input_format", referenced from:
_opt_format in FFPlayer(main.o)
"_av_find_opt", referenced from:
_opt_default in cmdutils.o
"_av_find_stream_info", referenced from:
_decode_thread in FFPlayer(main.o)
"_av_free", referenced from:
_SDL_main in FFPlayer(main.o)
_free_subpicture in FFPlayer(main.o)
_video_thread in FFPlayer(main.o)
_packet_queue_get in FFPlayer(main.o)
"_av_free_packet", referenced from:
_sdl_audio_callback in FFPlayer(main.o)
_video_thread in FFPlayer(main.o)
_subtitle_thread in FFPlayer(main.o)
_packet_queue_flush in FFPlayer(main.o)
_decode_thread in FFPlayer(main.o)
"_av_freep", referenced from:
_free_subpicture in FFPlayer(main.o)
_packet_queue_flush in FFPlayer(main.o)
"_av_get_bits_per_sample_format", referenced from:
_sdl_audio_callback in FFPlayer(main.o)
"_av_get_int", referenced from:
_video_thread in FFPlayer(main.o)
"_av_get_string", referenced from:
_set_context_opts in cmdutils.o
"_av_gettime", referenced from:
_SDL_main in FFPlayer(main.o)
_get_master_clock in FFPlayer(main.o)
_video_display in FFPlayer(main.o)
_get_video_clock in FFPlayer(main.o)
_stream_component_open in FFPlayer(main.o)
_sdl_audio_callback in FFPlayer(main.o)
_stream_pause in FFPlayer(main.o)
...
"_av_iformat_next", referenced from:
_show_formats in cmdutils.o
"_av_init_packet", referenced from:
_SDL_main in FFPlayer(main.o)
_decode_thread in FFPlayer(main.o)
"_av_log", referenced from:
_decode_thread in FFPlayer(main.o)
"_av_malloc", referenced from:
_packet_queue_put in FFPlayer(main.o)
"_av_mallocz", referenced from:
_SDL_main in FFPlayer(main.o)
"_av_metadata_get", referenced from:
_decode_thread in FFPlayer(main.o)
"_av_oformat_next", referenced from:
_show_formats in cmdutils.o
"_av_open_input_file", referenced from:
_decode_thread in FFPlayer(main.o)
"_av_protocol_next", referenced from:
_show_formats in cmdutils.o
"_av_read_frame", referenced from:
_decode_thread in FFPlayer(main.o)
"_av_read_pause", referenced from:
_decode_thread in FFPlayer(main.o)
"_av_read_play", referenced from:
_decode_thread in FFPlayer(main.o)
"_av_realloc", referenced from:
_opt_default in cmdutils.o
"_av_register_all", referenced from:
_SDL_main in FFPlayer(main.o)
"_av_set_string3", referenced from:
_opt_default in cmdutils.o
_set_context_opts in cmdutils.o
"_av_strdup", referenced from:
_parse_options in cmdutils.o
"_av_strlcat", referenced from:
_show_help_options in cmdutils.o
"_av_strlcpy", referenced from:
_show_help_options in cmdutils.o
_SDL_main in FFPlayer(main.o)
"_avcodec_alloc_context2", referenced from:
_SDL_main in FFPlayer(main.o)
"_avcodec_alloc_frame", referenced from:
_video_thread in FFPlayer(main.o)
"_avcodec_close", referenced from:
_stream_component_close in FFPlayer(main.o)
"_avcodec_decode_audio3", referenced from:
_sdl_audio_callback in FFPlayer(main.o)
"_avcodec_decode_subtitle2", referenced from:
_subtitle_thread in FFPlayer(main.o)
"_avcodec_decode_video2", referenced from:
_video_thread in FFPlayer(main.o)
"_avcodec_find_decoder", referenced from:
_stream_component_open in FFPlayer(main.o)
"_avcodec_flush_buffers", referenced from:
_sdl_audio_callback in FFPlayer(main.o)
_video_thread in FFPlayer(main.o)
_subtitle_thread in FFPlayer(main.o)
"_avcodec_open", referenced from:
_stream_component_open in FFPlayer(main.o)
"_avcodec_register_all", referenced from:
_SDL_main in FFPlayer(main.o)
"_avcodec_thread_init", referenced from:
_stream_component_open in FFPlayer(main.o)
"_avcodec_version", referenced from:
_print_all_lib_versions in cmdutils.o
"_avdevice_register_all", referenced from:
_SDL_main in FFPlayer(main.o)
"_avdevice_version", referenced from:
_print_all_lib_versions in cmdutils.o
"_avfilter_version", referenced from:
_print_all_lib_versions in cmdutils.o
"_avformat_alloc_context", referenced from:
_SDL_main in FFPlayer(main.o)
"_avformat_seek_file", referenced from:
_decode_thread in FFPlayer(main.o)
"_avformat_version", referenced from:
_print_all_lib_versions in cmdutils.o
"_avpicture_alloc", referenced from:
_SDL_main in FFPlayer(main.o)
"_avutil_version", referenced from:
_print_all_lib_versions in cmdutils.o
"_dump_format", referenced from:
_decode_thread in FFPlayer(main.o)
"_parse_date", referenced from:
_parse_time_or_die in cmdutils.o
"_sws_getCachedContext", referenced from:
_video_thread in FFPlayer(main.o)
"_sws_getContext", referenced from:
_SDL_main in FFPlayer(main.o)
"_sws_scale", referenced from:
_video_thread in FFPlayer(main.o)
"_swscale_version", referenced from:
_print_all_lib_versions in cmdutils.o
"_url_feof", referenced from:
_decode_thread in FFPlayer(main.o)
"_url_ferror", referenced from:
_decode_thread in FFPlayer(main.o)
"_url_ftell", referenced from:
_SDL_main in FFPlayer(main.o)
"_url_set_interrupt_cb", referenced from:
_decode_thread in FFPlayer(main.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)Can someone plz help me, thanx guys. I have checked that SDL.Framework and I dont see any problem in it. Does I have to add some library in my project to run this project or in mac.
-
Salty Game Music
31 mai 2011, par Multimedia Mike — GeneralHave you heard of Google’s Native Client (NaCl) project ? Probably not. Basically, it allows native code modules to run inside a browser (where ‘browser’ is defined pretty narrowly as ‘Google Chrome’ in this case). Programs are sandboxed so they aren’t a security menace (or so the whitepapers claim) but are allowed to access a variety of APIs including video and audio. The latter API is significant because sound tends to be forgotten in all the hullabaloo surrounding non-Flash web technologies. At any rate, enjoy NaCl while you can because I suspect it won’t be around much longer.
After my recent work upgrading some old music synthesis programs to user more modern audio APIs, I got the idea to try porting the same code to run under NaCl in Chrome (first Nosefart, then Game Music Emu/GME). In this exercise, I met with very limited success. This blog post documents some of the pitfalls in my excursion.
Infrastructure
People who know me know that I’m rather partial — to put it gently — to straight-up C vs. C++. The NaCl SDK is heavily skewed towards C++. However, it does provide a Python tool called init_project.py which can create the skeleton of a project and can do so in C with the'-c'
option :./init_project.py -c -n saltynosefart
This generates something that can be built using a simple ‘make’. When I added Nosefart’s C files, I learned that the project Makefile has places for project-necessary CFLAGS but does not honor them. The problem is that the generated Makefile includes a broader system Makefile that overrides the CFLAGS in the project Makefile. Going into the system Makefile and changing
"CFLAGS ="
->"CFLAGS +="
solves this problem.Still, maybe I’m the first person to attempt building something in Native Client so I’m the first person to notice this ?
Basic Playback
At least the process to create an audio-enabled NaCl app is well-documented. Too bad it doesn’t seem to compile as advertised. According to my notes on the matter, I filled inPPP_InitializeModule()
with the appropriate boilerplate as outlined in the docs but got a linker error concerning get_browser_interface().Plan B : C++
Obviously, the straight C stuff is very much a second-class citizen in this NaCl setup. Fortunately, there is already that fully functional tone generator example program in the limited samples suite. Plan B is to copy that project and edit it until it accepts Nosefart/GME audio instead of a sine wave.The build system assumes all C++ files should have .cc extensions. I have to make some fixes so that it will accept .cpp files (either that, or rename all .cpp to .cc, but that’s not very clean).
Making Noise
You’ll be happy to know that I did successfully swap out the tone generator for either Nosefart or GME. Nosefart has a slightly fickle API that requires revving the emulator frame by frame and generating a certain number of audio samples. GME’s API is much easier to work with in this situation — just tell it how many samples it needs to generate and give it a pointer to a buffer. I played NES and SNES music play through this ad-hoc browser plugin, and I’m confident all the other supported formats would have worked if I went through the bother of converting the music data files into C headers to be included in the NaCl executable binaries (dynamically loading data via the network promised to be a far more challenging prospect reserved for phase 3 of the project).Portable ?
I wouldn’t say so. I developed it on Linux and things ran fine there. I tried to run the same binaries on the Windows version of Chrome to no avail. It looks like it wasn’t even loading the .nexe files (NaCl executables).Thinking About The (Lack Of A) Future
As I was working on this project, I noticed that the online NaCl documentation materialized explicit banners warning that my NaCl binaries compiled for Chrome 11 won’t work for Chrome 12 and that I need to code to the newly-released 0.3 SDK version. Not a fuzzy feeling. I also don’t feel good that I’m working from examples using bleeding edge APIs that feature deprecation as part of their naming convention, e.g., pp::deprecated::ScriptableObject().Ever-changing API + minimal API documentation + API that only works in one browser brand + requiring end user to explicitly enable feature = … well, that’s why I didn’t bother to release any showcase pertaining to this little experiment. Would have been neat, but I strongly suspect that this is yet another one of those APIs that Google decides to deprecate soon.
See Also :